zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 68 (Rated for Div. 2) D. 1-2-K Game (博弈, sg函数,规律)

    D. 1-2-K Game
    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Alice and Bob play a game. There is a paper strip which is divided into n + 1 cells numbered from left to right starting from 0. There is a chip placed in the n-th cell (the last one).

    Players take turns, Alice is first. Each player during his or her turn has to move the chip 1, 2 or k cells to the left (so, if the chip is currently in the cell i, the player can move it into cell i - 1, i - 2 or i - k). The chip should not leave the borders of the paper strip: it is impossible, for example, to move it k cells to the left if the current cell has number i < k. The player who can't make a move loses the game.

    Who wins if both participants play optimally?

    Alice and Bob would like to play several games, so you should determine the winner in each game.

    Input
    The first line contains the single integer T (1 ≤ T ≤ 100) — the number of games. Next T lines contain one game per line. All games are independent.

    Each of the next T lines contains two integers n and k (0 ≤ n ≤ 109, 3 ≤ k ≤ 109) — the length of the strip and the constant denoting the third move, respectively.

    Output
    For each game, print Alice if Alice wins this game and Bob otherwise.

    Example
    inputCopy
    4
    0 3
    3 3
    3 4
    4 4
    outputCopy
    Bob
    Alice
    Bob
    Alice

    题意:
    当前在n位置,每一次可以向左走1,2,或者k步,最左的位置是0,不能走到0的左边, 二人博弈问题,谁没法再走的时候就输掉,问先手必赢还是后手必赢。
    思路:

    首先确定的是 0位置是必输位置,因为 1 2 和k这三个位置可以一步就走到0位置,所以这3个位置是必赢位置,以此规律,我们可以递推出sg函数。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int sg[maxn];
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
    	//freopen("D:\common_textcode_stream\out.txt","w",stdout);
    	
    	int n,k;
    	n=100;
    	cin>>k;
    	sg[0]=0;
    	sg[1]=1;
    	sg[2]=1;
    	repd(i,3,n)
    	{
    		if((i-k)>=0)
    		{
    			if(sg[i-1]==0||sg[i-2]==0||sg[i-k]==0)
    			{
    				sg[i]=1;
    			}
    		}else
    		{
    			if(sg[i-2]==0||sg[i-1]==0)
    			{
    				sg[i]=1;
    			}
    		}
    	}
    	repd(i,0,n)
    	{
    		cout<<i<<" "<<sg[i]<<endl;
    
    	}
    	
    	
    	
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    通过sg函数打表分析可以得出, 有以下规律
    如果k是3的倍数,那么sg函数是k+1长度的循环节,对循环节取模后,判断n是否是k,如果是k,那么k位置必赢,否则判断是否是3的倍数。
    如果k不是3的倍数,那么判断n是否是3的倍数即可。
    
    比赛时看错表,推出个错规律,wa了3次,深夜写这个博客算给自己一个记性吧。
    

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int* p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
     
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_textcode_stream\out.txt","w",stdout);
     
        int t;
        ll n, k;
        gbtb;
        cin >> t;
        while (t--)
        {
            cin >> n >> k;
            if (k % 3 == 0)
            {
                n %= (k + 1);
                if (n == k)
                {
                    cout << "Alice" << endl;
                } else
                {
                    if (n % 3 == 0)
                        cout << "Bob" << endl;
                    else
                        cout << "Alice" << endl;
                }
                // return 0;
                continue;
            }
     
            if ((n % 3) == 0 )
            {
                cout << "Bob" << endl;
            } else
            {
                cout << "Alice" << endl;
            }
        }
     
     
     
        return 0;
    }
     
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
     
     
     
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    git push要输入密码问题
    excel换行
    React的diff算法
    https的通信过程
    一道面试题的分析
    Mac将应用拖入Finder工具栏
    React获取组件实例
    Warning: Received `false` for a non-boolean attribute `xxx`.
    warning: React does not recognize the xxx prop on a DOM element
    webpack开发模式和生产模式设置及不同环境脚本执行
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11186681.html
Copyright © 2011-2022 走看看