单词博弈

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


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 单词博弈
{
    class Program
    {
        static String str;
        static int length;
        static int[] mask;
        static int[] permutationCache;
        static int[] stateCache;
        /// <summary>
        /// 判断是否为递增
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        private static int checkPermutation(int state)
        {
            //如果这个数组里本身有值直接取出返回
            if (permutationCache[state] != -1)
            {
                return permutationCache[state];
            }
            char previous = char.MinValue;
            char current;
            int result = 1;
            for (int i = 0; i < length; ++i)
            {
                //循环取出每一位忽略掉0 此时mark是1000..这种形式
                if ((mask[i] & state) == 0)
                {
                    continue;
                }
                //取出当前的字符
                current = str[i];
                if (current <= previous)
                {
                    result = 0;
                    break;
                }
                previous = current;
            }
            //将这个数的值保存在数组里
            return permutationCache[state] = result;
        }
        /// <summary>
        /// 判断谁赢
        /// </summary>
        /// <param name="state">数对应的位图</param>
        /// <returns></returns>
        private static int checkState(int state)
        {
            //如果状态表中有值直接取出,这里这样用是可以的因为每个对应一个1111去掉之后就是0111,1011,1001,0001每个都不同
            if (stateCache[state] != -1)
            {
                return stateCache[state];
            }
            int result = 0;
            int next;
            for (int i = 0; i < length; ++i)
            {
                //忽略掉为0的
                if ((mask[i] & state) == 0)
                {
                    continue;
                }
                next = state & ~mask[i];
                if (checkPermutation(next) == 1 || checkState(next) == 0)
                {
                    result = 1;
                    break;
                }
            }
            
            return stateCache[state] = result;
        }
        public static int who(String word)
        {
            str = word;
            length = word.Length;
            permutationCache = new int[1 << length];
            for (int i = 0; i < permutationCache.Length; i++)
            {
                permutationCache[i] = -1;
            }
            //状态对应表每次使用who都要重新创建
            stateCache = new int[1 << length];
            for (int i = 0; i < permutationCache.Length; i++)
            {
                stateCache[i] = -1;
            }
            mask = new int[16];
            for (int i = 0; i < 16; ++i)
            {
                mask[i] = 1 << i;
            }
            return checkState((1 << length) - 1);
        }
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //string str = "onmlkjihgfedcba";
            //Console.WriteLine(str.Length);
            //for (int i = 0; i < 10; i++)
            //{
            
            //    Console.WriteLine(who(str));
            //}
            string str = "cab";
            string str2 = "cba";
            Console.WriteLine(who(str));
            Console.WriteLine(who(str2));
            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed);
         
            Console.ReadKey();
        }
    }
}


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值