牛客小白月赛7 — 自杀游戏(递推博弈)

链接:https://www.nowcoder.com/acm/contest/190/B
来源:牛客网
 

题目描述

Alice和Bob产生了不可调节的矛盾,于是他们相约一起玩一个自杀游戏,输的人就会从这个世界上消失。

游戏开始时,Alice手上拿着一个定时炸弹,炸弹有个倒计时t。炸弹在t=0时刻会爆炸,此时手上拿着炸弹的人会从这个世界上消失。为了增加游戏乐趣,他们约定每个人拿到炸弹后可以选择将炸弹的时间调快d秒(d ∈ [a,b]),或者不调。每次交换炸弹会消耗1秒(假设调节炸弹时间不需要消耗时间)。

问题来了,如果双方都足够聪明,谁会活下去呢?

输入描述:

第一行有三个整数t,a,b,分别表示炸弹初始时刻的倒计时,可调节时间的范围。(0 ≤ t ≤ 105,1 ≤ a ≤ b ≤ 10)

输出描述:

若Alice存活则输出"Alice",若Bob存活则输出"Bob"。

题解:

可以简化成两人轮流拿石子,每个人只可以拿1个或者a+1 ~ b+1个 ,举个例子:假设输入的a = 3,b = 5,那么每轮可以取走1,4,5,6个;

先手必胜态:

1、4、5、6 (在1到3之间的数,每轮只能拿一个,奇数必胜,偶数必败,也就是说2必败,3必胜)

先手想必胜,那他在取走后到达必败态就行了(现在可以看出2为必败态),1+2、4+2、5+2、6+2都是先手的必胜态,他可以控制他取走石子后让对手处在2这个必败态。(必胜必败态都是对于先手而言)

必胜态:1、3、4、5、6、7、8

必败态:2

接下来是数字9,先手取走后:9-1、9-4、9-5、9-6,这些数字都是必胜态,那么后手就必胜,先手必败。

现在必败态为:2、9

接下来1+9、4+9、5+9、6+9又都是先手的必胜态,他依然可以控制他取走石子后让对手处在9这个必败态。

本题n范围比较小,可以一直这样模拟下去。

AC代码:

 #include<iostream>
 using namespace std;
 const int maxn = 1e5+55;
 int vis[maxn];         //保存先手的状态
 int ans[20];           //保存每局可以拿的个数
 int main()
 {
     int t,a,b;
     while(cin>>t>>a>>b)
     {
         memset(vis,0,sizeof(vis));
         ans[0] = 1;
         int n = 1;
         for(int i=1;i<=a;i+=2)      //标记1~a的必胜态,奇数必胜
             vis[i] = 1;
         for(int i=a+1;i<=b+1;i++) 
         {
             ans[n++] = i;
             vis[i] = 1;
         }
         for(int i=2;i<t;i++)      
         {
             if(!vis[i])              //如果i没有被标记为必胜态,那就是必败态
             {
                 for(int j=0;j<n;j++) //标记能到达必败态i的点
                    vis[ans[j]+i] = 1;
             }
         }
         if(vis[t]) cout<<"Alice"<<endl;
         else cout<<"Bob"<<endl;
     }
     return 0;
 }

猜你喜欢

转载自blog.csdn.net/qq_41157137/article/details/83019675