VOJ - Ildar Yalalov (初级博弈论)

Ildar Yalalov

题目链接: I - Ildar Yalalov Gym - 101808I

题意

给你N堆石头,每堆Ai个数,(1 ≤ N ≤ 100) (1 ≤ A**i ≤ 106) ,让两个人,进行如下操作

1) Remove one stone from any pile.

2) Remove one stone from every pile if every pile has at least 1 stone.


思路

这很像原来小学时的拿石块问题,就是每个人有机会拿两块或一块。

首先有一个简单的结论,如果两个人拿石头到了最后一个阶段(无法实现操作二时),谁面临的石头是奇数个谁一定赢。
我就从奇数堆开始分析,从3+2,3+1(有三组,最小的一份是石头数量是一,另外多出来了两个额外的)
推到3+3+2,在推到3+3+3+2,然后发现如果组数是奇数,那么就只需要判断余数的情况。
在从偶数堆开始判断,从4+2,4+3开始倒推,规律就显而易见了。
这道题最好找个合适的小数据开始倒推


代码

#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mp make_pair

typedef double db;
typedef long long ll;
const int MAXN = (int)1e6+7;
const int INF = (int)0x3f3f3f3f;

int A[MAXN];
int N;

int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

    int T;
    cin >> T;
    while (T --) {
        cin >> N;
        int minV = INF;
        int sum = 0;
        rep(i,1,N) {
            cin >> A[i];
            if (A[i] < minV) minV = A[i];
            sum += A[i];
        }
        int rema = sum - minV*N;
        if (N&1) {
            if (sum&1) cout << "Yalalov" << endl;
            else       cout << "Shin" << endl;
        }else {
            if (minV&1) cout << "Yalalov" << endl;
            else {
                if (rema&1) cout << "Yalalov" << endl;
                else        cout << "Shin" << endl;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40513946/article/details/81069573