您的位置:首页 > 其它

HDU 1404 Digital Deletions

2016-08-03 20:48 190 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/29195/origin



题意:有一些数,每次操作:1、可以选择一个位置,将其数变为比原来小的非负数。2、如果一个位置是0,可以把包括该位置以内以及所有右边的数去掉。不能操作的人输。



思路:长度不超过6,因为可以先打一个状态表。注意一点,如果第一个位置是0,那么先手必胜,而且打表取数时也不可以把第一个位置取为0(否则必败)。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007

bool f[1000009];

void init()
{
f[0] = true;
int digit[10];
int v[10];
int temp,len;
int now;
v[1] = 1;
rep(i,2,6) v[i] = v[i-1] * 10;
rep(i,1,999999)
{
bool ans = false;
temp = i;
now = len = 0;
while( temp )
digit[++len] = temp % 10 , temp/=10;
Rrep(j,len,1) //枚举每一位
{
if (digit[j]==0) ans |= !f[now];
else
{
int up;
if ( j == len )
up = digit[j]-1;
else up = digit[j];
rep( k , 1 , up ) //枚举取多少
ans |= !f[ i - k * v[j] ];
}
now = now * 10 + digit[j];
}
f[i] = ans;
}
}

int main()
{
char s[10];
Clean(f,0);
init();
while(~scanf("%s",s))
{
if ( s[0] == '0' )
puts("Yes");
else{
int len = strlen(s);
int now = 0;
rep(i,0,len-1)
now = now * 10 + s[i] - '0';
puts( f[now]==0 ?"No":"Yes" );
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  博弈论