参与英雄会第一届在线编程大赛:单词博弈
2013-12-15 20:18
204 查看
以下是我的源码,为什么会测试失败???哈哈找到问题了
请大侠指点,我觉得应该对了啊,而且算法经典。
本第一次在线编程大赛由文思海辉冠名,题目如下: 甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么? 输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。 输出:1表示甲可以赢,0表示甲不能赢。 例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。
又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。 函数头部: C:int who (const char * word); C++:int who (string word); Java:public static int who(String in); C# :public static int who(string word);
/* 设计思路,先要找到最大有序增长的子序列长度,然后由于甲乙都足够聪明所以甲要赢只有两种情况
1,最大有序增长的子序列长度比单词长度只小1
2, 最大有序增长的子序列长度比单词长度相差2个字符以上,单词长度为偶数甲可以赢
*/
int who (char * word)
{
char* string = word;
int wordlen = strlen(string); // 获取单词的字符长度
int* subgrowlen = NULL;
int subgrowlenmax = 1; // 最大有序增长的子串长度
int i = 0, j = 0;
subgrowlen = (int*)malloc(wordlen * sizeof(int)); // 为存储单词中从左到右每个字符的最大有序增长的子串长度开辟空间
for(i = 0; i < 100; i++) subgrowlen[i] = 1; // 默认从左到右每个字符的最大有序增长的子串长度都为自己,即为1
/* 从左到右计算单词中以当前字符为单词结尾的最大有序增长的子串长度*/
for(i = 1; i < wordlen; i++)
{
for(j = i - 1; j>= 0; j--)
{
if(*(string+i) > *(string+j)) // 以当前字符往单词前部比较是否有隶属于本字符的序列
{
if(subgrowlen[i] < subgrowlen[j]+1) // 如果有,则比较当前已有的最大有序增长的子串长度是否还可扩展
{
subgrowlen[i] = subgrowlen[j]+1; // 可以扩展则更新以当前字符为单词结尾的最大有序增长的子串长度
if(subgrowlenmax < subgrowlen[i])
subgrowlenmax = subgrowlen[i]; // 更新所有单词中的最大有序增长的子串长度
}
}
}
}
if((wordlen - subgrowlenmax) < 2)
return 1; /* 最大有序增长的子串长度和单词只差一个字符(一个不差没有意义,忽略),甲必赢(足够聪明)*/
else
{
/*甲乙足够聪明,所以当甲不能一步胜利的话也不可能给乙创造机会,同理乙也不会给甲创造机会。
最终是看谁走到只剩下无序2个字符的那一步,再走一步就胜利了*/
if(wordlen % 2 == 0) return 1; // 当单词长度为偶数时,甲先走甲可以胜利
else return 0; // 当单词长度为奇数时,甲先走乙可以胜利
}
}
请大侠指点,我觉得应该对了啊,而且算法经典。
本第一次在线编程大赛由文思海辉冠名,题目如下: 甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么? 输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。 输出:1表示甲可以赢,0表示甲不能赢。 例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。
又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。 函数头部: C:int who (const char * word); C++:int who (string word); Java:public static int who(String in); C# :public static int who(string word);
/* 设计思路,先要找到最大有序增长的子序列长度,然后由于甲乙都足够聪明所以甲要赢只有两种情况
1,最大有序增长的子序列长度比单词长度只小1
2, 最大有序增长的子序列长度比单词长度相差2个字符以上,单词长度为偶数甲可以赢
*/
int who (char * word)
{
char* string = word;
int wordlen = strlen(string); // 获取单词的字符长度
int* subgrowlen = NULL;
int subgrowlenmax = 1; // 最大有序增长的子串长度
int i = 0, j = 0;
subgrowlen = (int*)malloc(wordlen * sizeof(int)); // 为存储单词中从左到右每个字符的最大有序增长的子串长度开辟空间
for(i = 0; i < 100; i++) subgrowlen[i] = 1; // 默认从左到右每个字符的最大有序增长的子串长度都为自己,即为1
/* 从左到右计算单词中以当前字符为单词结尾的最大有序增长的子串长度*/
for(i = 1; i < wordlen; i++)
{
for(j = i - 1; j>= 0; j--)
{
if(*(string+i) > *(string+j)) // 以当前字符往单词前部比较是否有隶属于本字符的序列
{
if(subgrowlen[i] < subgrowlen[j]+1) // 如果有,则比较当前已有的最大有序增长的子串长度是否还可扩展
{
subgrowlen[i] = subgrowlen[j]+1; // 可以扩展则更新以当前字符为单词结尾的最大有序增长的子串长度
if(subgrowlenmax < subgrowlen[i])
subgrowlenmax = subgrowlen[i]; // 更新所有单词中的最大有序增长的子串长度
}
}
}
}
if((wordlen - subgrowlenmax) < 2)
return 1; /* 最大有序增长的子串长度和单词只差一个字符(一个不差没有意义,忽略),甲必赢(足够聪明)*/
else
{
/*甲乙足够聪明,所以当甲不能一步胜利的话也不可能给乙创造机会,同理乙也不会给甲创造机会。
最终是看谁走到只剩下无序2个字符的那一步,再走一步就胜利了*/
if(wordlen % 2 == 0) return 1; // 当单词长度为偶数时,甲先走甲可以胜利
else return 0; // 当单词长度为奇数时,甲先走乙可以胜利
}
}
相关文章推荐
- 庞果网英雄会第一届在线编程大赛:单词博弈
- 庞果网英雄会第一届在线编程大赛:单词博弈
- 英雄会第一届在线编程大赛:单词博弈 (C++代码) ---miss若尘
- 英雄会第一届在线编程大赛:单词博弈 (解题思路) ---miss若尘
- 英雄会第一届在线编程大赛:单词博弈
- 文思海辉第一届在线编程大赛:单词博弈 -dp+博弈
- 单词博弈的c#求解--在线编程大赛的题
- 英雄会第一届在线编程大赛解题思路
- 英雄会第二届在线编程大赛·线上初赛:AB数
- csdn英雄会题解之几个bing--微软必应·英雄会第三届在线编程大赛
- 微软必应·英雄会第三届在线编程大赛 “几个bing” 题解
- [转]微软联合CSDN英雄在线编程大赛
- 微软必应-英雄会第三届在线编程大赛:几个Bing?【英雄会】
- 微软必应·英雄会第三届在线编程大赛:几个bing?
- 微软必应·英雄会第三届在线编程大赛:几个bing?
- 算法与数据结构(2)--英雄会第三届在线编程大赛:几个bing
- 英雄会第四届在线编程大赛·线上初赛:带通配符的数
- 英雄会第四届在线编程大赛·线上初赛:带通配符的数
- 英雄会第四届在线编程大赛·线上初赛:带通配符的数
- 庞果英雄会第二届在线编程大赛·线上初赛:AB数