本第一次在线编程大赛由文思海辉冠名,题目如下:
甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么?
输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。
输出:1表示甲可以赢,0表示甲不能赢。
例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。
又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。
首先 一连串英文小写字母,长度不超过15,让我们测试起来是相当简单,也不需要toLowerCase了,最开始的状态也不是严格单增的,题目还是相当严密的,比如一开始就是ad,这就有歧意了。
再者就是最难懂的地方就是,甲乙足够聪明,看样子水还蛮深的,其实这就是告诉我们输赢已定,字符要么是必败,要么是必胜,(都那么聪明,还不如自己一个人研究的好,还需要两个人玩干嘛哦),所以这个题目是在不知不觉中透露了很多信息,相当严密。
每个题目其实就差一个切入口,程序解题,肯定是递归,不然人解就行了,还需要计算机干什么
那我们就从简单的开始分析起,就用题目的bad为例子,如果删掉b,或者a,那就胜利了,删掉d就输了,当然甲足够聪明,当然是不会删d的,那就是甲赢,当然这题比较简单,删一个就剩下一个严格递增的序列,比较好判断,如果我在加大一点难度,badd呢,不管我删掉哪个字符剩下的都是必死无疑,这就毫无可赢的可能啊,哪怕给我一个选择删掉一个字符后,剩下的是必败的,我也就胜了,哦,这不就是我们要的切入口么,判断是不是胜利,就看删掉某个字符剩下的有没有一个是必败的,有就是胜利,没有就是失败
那怎么知道这个字符串是必胜还是必败呢?
2个字母的字符串,我们肯定是可以确定的吧,那三个的我们不也就可以知道了嘛,比如bad删掉b,剩下ad递增的,ad就是必败的,删掉a同样,删掉d剩一个ba必胜的,那bad就是必胜的,同理分析aaa,删掉哪个a都是剩下一个必胜的aa,那就是必败了,同理4个字符的可以分析,那递归每个字符都可以判断了
,我暂且直接贴代码,下回补全我写代码的思路,有问题可以直接留言,对了如果谁想去挑战,记得一定要把system语句删掉,一样的代码我把system删掉,就通过了。
public static Map<String,String> bibai=new HashMap<String,String>();
public static Map<String,String> bisheng=new HashMap<String,String>();
public static char[] chars ;
public static void main(String[] args)
{
System.out.println(who("aaa"));
}
public static int who(String word)
{
Date date=new Date();
word=word.toLowerCase();
chars=word.toCharArray();
int length=word.length();
for(int i=2;i<length;i++)
{
Sort(word,i);
}
if(isBiSheng(word))
{
Date date1=new Date();
long l=date1.getTime()-date.getTime();
System.out.println(l+"毫秒");
return 1;
}
else
{
Date date1=new Date();
long l=date1.getTime()-date.getTime();
System.out.println(l+"毫秒");
return 0;
}
}
public static void Sort(String source,int count)
{
if(count==2)
{
for(int i=0;i<source.length();i++)
{
for(int j=i+1;j<source.length();j++)
{
String strGroup=String.valueOf(chars[i])+String.valueOf(chars[j]);
if(chars[i]<chars[j])
{
bibai.put(strGroup, strGroup);
}else
{
bisheng.put(strGroup, strGroup);
}
}
}
}else
{
StringBuffer stringBuff=new StringBuffer();
combine(source.toCharArray(), 0, count, stringBuff);
}
}
public static boolean sortASC(String str)
{
char[] chars=str.toCharArray();
for(int i=0;i<chars.length-1;i++)
{
if(chars[i]>=chars[i+1])
{
return false;
}
}
return true;
}
public static boolean isBiSheng(String str)
{
if(sortASC(str))
{
return false;
}
for(int i=0;i<str.length();i++)
{
String strNew=str.substring(0, i)+str.substring(i+1);
if(bisheng.get(strNew)==null)
{
return true;
}
}
return false;
}
public static void combine(char []chs, int begin, int number, StringBuffer stringBuff){
if(number == 0){
if(isBiSheng(stringBuff.toString()))
{
bisheng.put(stringBuff.toString(), stringBuff.toString());
}
else{
bibai.put(stringBuff.toString(), stringBuff.toString());
}
return ;
}
if(begin == chs.length){
return;
}
stringBuff.append(chs[begin]);
combine(chs, begin + 1, number - 1, stringBuff);
stringBuff.delete(stringBuff.length()-1,stringBuff.length());
combine(chs, begin + 1, number, stringBuff);
}