英雄会第一届在线编程大赛解题思路

其实往往看到编程题目,作为一个java程序员,往往觉得语言不占优势,好像写了也没什么机会,我个人觉得其实在快慢效率上,真正的还是思想,大胆写,java有那么好的api,java源代码,好的开源社区,写起来只会更快,其实挑战编程题目还是很让人受益的,话不多说,开始分析:
题目详情

本第一次在线编程大赛由文思海辉冠名,题目如下:

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序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);
	}


 

 

    

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值