您的位置:首页 > 运维架构

USACO 2009 Open Silver 3.Cow Digit Game简单博弈论

2016-08-28 16:01 417 查看
Description
Bessie is playing a number game against Farmer John, and she wants you to help her achieve victory.

Game i starts with an integer N_i (1 <= N_i <= 1,000,000). Bessie goes first, and then the two players alternate turns. On each turn, a player can subtract either the larges digit or the smallest non-zero digit from the current number to obtain a new number.
For example, from 3014 we may subtract either 1 or 4 to obtain either 3013 or 3010, respectively. The game continues until the number becomes 0, at which point the last player to have taken a turn is the winner.

Bessie and FJ play G (1 <= G <= 100) games. Determine, for each game, whether Bessie or FJ will win, assuming that both play perfectly (that is, on each turn, if the current player has a move that will guarantee his or her win, he or she will take it).

Consider a sample game where N_i = 13. Bessie goes first and takes 3, leaving 10. FJ is forced to take 1, leaving 9. Bessie takes the remainder and wins the game.

Input

* Line 1: A single integer: G

* Lines 2..G+1: Line i+1 contains the single integer: N_i

Output

* Lines 1..G: Line i contains "YES" if Bessie can win game i, and "NO" otherwise.

Sample Input

2

9

10

Sample Output

YES

NO

OUTPUT DETAILS:

For the first game, Bessie simply takes the number 9 and wins. For the second game, Bessie must take 1 (since she cannot take 0), and then FJ can win by taking 9.

题意:对于一个初始的数n,每次可以减去这个数的数位中最大的那一位,或是最小的非零的那一位,如3014中最大的是4,最小非零的是1,可以得到3014-1=3013或3014-4=3010,两个人轮流操作,减到到0的人获胜。

最近迷上了这些简单的博弈论了呢~

显然,当轮到一个人时,n已经为0,则此时就是一个必败态,令必败态的sg值为0,必胜态的sg值为1,那么我们就可以从小到大递推了。

设当前数i中最大的一位是maxi,最小的非零位是mini,那么若i-maxi和i-mini都对应一个必胜态,那么i就是一个必败态;若i-maxi和i-mini中有一个是必败态,那么i就是一个必胜态。

至于找最大位和最小非零位,鉴于数据范围不是太变态,暴力拆分就可以了。

代码:

#include<stdio.h>
int sg[1000010],num[10],len;
int maxi,mini;
int main()
{
sg[0]=0;
int i,t,n;
len=0;
for(i=1;i<=1000000;i++)
{
t=i;
maxi=0;
mini=10;
while(t)
{
if(t%10>maxi)
maxi=t%10;
if(t%10>0&&t%10<mini)
mini=t%10;
t/=10;
}
sg[i]=(sg[i-maxi]&sg[i-mini])^1;
}
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&t);
if(sg[t])
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: