庞果网-单词博弈

原创 2013年12月02日 12:45:57
 
题目详情

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明,甲先开始,问他能赢么?

输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。

输出:1表示甲可以赢,0表示甲不能赢。

例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。

又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。

 

此题属于明显的博弈问题,但是比较遗憾的是在我的acm生涯中没接触过博弈论这个部分,因此刚开始尝试利用模拟的方法解决,利用极大极小搜索+alpha beta剪枝找到最优解,实现后提交结果超时了,继续优化后没有发现比较好的剪枝方法,因此不得不换个思路。

 

百度了下博弈论的基本概念,顿时茅塞顿开,解决这个问题,只需要知道两个基本概念即可!

1.一个局势只能是必胜局势或必败局势两种
2.如果一个局势能通过操作变为必败局势,那么这个局势就是必胜的,否则是必败的

 

此题即求初始的序列是否是必胜局势,不难发现此题的必败局势是升序序列,因为在到达这个局势时对手已经赢了,我们可以枚举当前局势的每种子局势,判断它是否是必胜还是必败,然后得到当前局势的状态。

 

static const int fastbit[32] = {
    0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
    31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};

#define FASTBIT(X) (fastbit[((unsigned int)(((X)&-(X))*0x077CB531U))>>27])

int state[(1<<16)-1]; //0代表必败,1代表必胜

int who(char *word)
{
    int len;
    int i ,j ,t ,k;
    len = strlen(word);
    
    memset(state, 0, sizeof(state));
    
    for(i = 1 ;i < (1<<len) ;i ++) {
        
        t = i;
        k = -1;
        while(t) {
            
            j = FASTBIT(t);
            if(k >= 0 && word[k] >= word[j]) { //判断是否升序
                break;
            }
            k = j;
            t &= ~(t&-t);
        }
        
        if(!t) {
            continue;
        }
        
        t = i;
        k = 0;
        while(t && !state[i]) { //枚举当前局势的子局势
            
            j = FASTBIT(t);
            state[i] = state[(t&~(1<<j))|k]^1;
            k = ((1<<(j+1))-1)&i;
            t &= ~(t&-t);
        }
        
    }
    
    return state[(1<<len)-1];
}


 

庞果网 —在线编程 —单词博弈 — 特殊解法

英雄会第一届在线编程大赛:单词博弈  15 奖 剩余时间:9天12小时4分37秒 编程语言:C C++ Java C# 答题时长:120 分钟│难度等级: ...
  • u012932453
  • u012932453
  • 2013年12月11日 12:29
  • 892

单词博弈【已通过测试】

菜鸟来报道!     在Pongo上看到单词博弈的题目: 甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < ...
  • yi_dia
  • yi_dia
  • 2013年12月05日 15:56
  • 1354

庞果网英雄会第一届在线编程大赛:单词博弈

博客地址:http://www.cnblogs.com/TenosDoIt/p/3485090.html
  • tangzhangpeng
  • tangzhangpeng
  • 2013年12月21日 14:09
  • 617

单词博弈

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a 输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是...
  • qzyf1992
  • qzyf1992
  • 2013年12月07日 00:34
  • 1846

【单词博弈】

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ...
  • u012334315
  • u012334315
  • 2013年12月09日 20:12
  • 569

单词博弈 --- java实现

前段时间做了一道题,这里mark一下。 题目: 甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a 两个...
  • smile0198
  • smile0198
  • 2014年01月05日 22:37
  • 1288

单词博弈——利用map

单词博弈 甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a 例如: 输入 bad, 则甲可以删掉b或...
  • tcherry
  • tcherry
  • 2014年10月07日 14:24
  • 462

单词博弈C++版本

#include #include #include #include using namespace std ; // judge if district ascend order boo...
  • d_dd55
  • d_dd55
  • 2014年10月23日 20:35
  • 168

单词博弈-华为OJ

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c ...
  • zhang_jinhe
  • zhang_jinhe
  • 2016年09月04日 14:04
  • 413

博弈-Nim博弈

Nim博弈
  • wximo
  • wximo
  • 2014年05月13日 11:19
  • 816
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:庞果网-单词博弈
举报原因:
原因补充:

(最多只允许输入30个字)