• [USACO09OPEN]牛的数字游戏Cow Digit Game 博弈


    题目描述

    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 largest 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.

    贝茜和约翰在玩一个数字游戏.贝茜需要你帮助她.

    游戏一共进行了G(1≤G≤100)场.第i场游戏开始于一个正整数Ni(l≤Ni≤1,000,000).游

    戏规则是这样的:双方轮流操作,将当前的数字减去一个数,这个数可以是当前数字的最大数码,也可以是最小的非0数码.比如当前的数是3014,操作者可以减去1变成3013,也可以减去4变成3010.若干次操作之后,这个数字会变成0.这时候不能再操作的一方为输家. 贝茜总是先开始操作.如果贝茜和约翰都足够聪明,执行最好的策略.请你计算最后的赢家.

    比如,一场游戏开始于13.贝茜将13减去3变成10.约翰只能将10减去1变成9.贝茜再将9减去9变成0.最后贝茜赢.

    输入输出格式

    输入格式:

    * Line 1: A single integer: G

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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    2 
    9 
    10 
    
    输出样例#1: 复制
    YES 
    NO 
    

    说明

    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.

    考虑用 sg 函数,

    那么 sg[ i ]=mex( sg[ i-min ],sg[ i-max ]);

    然后 O(1) 询问即可;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize("O3")
    using namespace std;
    #define maxn 1000005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    inline ll rd() {
    	ll x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
    	ll ans = 1;
    	a = a % c;
    	while (b) {
    		if (b % 2)ans = ans * a%c;
    		b /= 2; a = a * a%c;
    	}
    	return ans;
    }
    
    int n;
    int sg[maxn];
    int vis[10];
    int mex() {
    	for (int i = 0;; i++) {
    		if (!vis[i])return  i;
    	}
    }
    
    void init(int Max) {
    	sg[0] = 0;
    	for (int i = 1; i <= Max; i++) {
    		int tmp = i; ms(vis);
    		int minn = 10, maxx = -1;
    		while (tmp) {
    			if(tmp%10!=0)
    			minn = min(minn, tmp % 10), maxx = max(maxx, tmp % 10);
    			tmp /= 10;
    		}
    		if (maxx != -1)vis[sg[i - maxx]] = 1;
    		if (minn != 10)vis[sg[i - minn]] = 1;
    		sg[i] = mex();
    	}
    }
    
    int main()
    {
    	//ios::sync_with_stdio(0);
    	rdint(n); init(maxn);
    	while (n--) {
    		int x; rdint(x);
    		if (sg[x] == 0)cout << "NO" << endl;
    		else cout << "YES" << endl;
    	}
        return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    Python学习32天(socket、tcp协议)
    Python学习第31天(异常、异常捕捉)
    Python之旅的第30天(过程记录,选课系统的基本实现)
    Python之旅的第29天(property补充、元类和自定义元类)
    Python之旅的第28天(描述符、类的装饰器)
    Python之旅的第27天(复习、习题实现、__enter__、__exit__)
    Python之旅第26天(__slots__等内置方法、软件开发规范)
    假期第二周
    假期第一周
    第十六周学习进度博客
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10006126.html
Copyright © 2020-2023  润新知