CF 1375 F. Integer Game (思维, 构造)

题目:传送门

题意

有三堆石堆,分别有 a, b, c 石子, 有两个人在玩游戏, 先手给出一个数 y,后手选择一堆石堆加上 y 的石子,后手不能连续两轮都选择同样的石堆。若后手操作完后,存在两堆石堆石子个数相等,则先手赢。若后手操作超过1000轮,则后手赢。

思路

首先,先手肯定能赢,我们假设 a < b < c;若后手上一轮是对石子最多的第 3 堆操作,那么,先手只要给出 c - b + c - a,那么后手只能选择让第 1 堆或者 第 2 堆加上 c - b + c - a;

若第 1 堆加上 c - b + c - a,则变为 2c - b, b, c;那么此时先手再给出 c - b;后手只能选择让 b 加上 c - b;或者让 c 加上 c - b;无论如何,都存在两堆石堆石子个数相等。

若第 2 堆加上 c - b + c - a,也同理。

那么现在考虑,如何让后手对石子最多的石堆操作。我们假设 a < b < c

那么首先,给出 c - b;那么后手只能选择对第 3 堆或者第 1 堆操作。

若对第 3 堆操作,则达到我们的目的。

若对第 1 堆操作,此时,先手再给出 c - b,则后手只能对第 3 堆操作,同样达到我们的目的。

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define UI unsigned int
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 0x3f3f3f3f
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
#define lb(x) ((x) & (-(x)))
#define dbg(x) cout<<#x<<" = "<<x<<endl;
using namespace std;

const int N = 1e6 + 5;

void FWT_xor(int a[], int n, int op) {

    for(int i = 1; i < n; i <<= 1) {

        for(int p = i << 1, j = 0; j < n; j += p) {

            for(int k = 0; k < i; k++) {

                int X = a[j + k], Y = a[i + j + k];

                a[j + k] = (X + Y);

                a[i + j + k] = (X - Y);

                if(op == -1) a[j + k] = a[j + k] / 2, a[i + j + k] = a[i + j + k] / 2;

            }

        }

    }

}

LL a[4], x;

void Go() {

    rep(i, 1, 3) {

        if(a[i] == max({a[1], a[2], a[3]})) {

            int j = 1; int k = 2;

            if(i == j) j = 3;

            if(i == k) k = 3;
            
            cout << a[i] - a[j] + a[i] - a[k] << endl;

            cin >> x;

            if(x == 0) return ;

            if(x == k) swap(j, k);

            a[j] += (a[i] - a[j]) + (a[i] - a[k]);
            
            cout << a[i] - a[k] << endl;
            
            cin >> x;

        }

    }

}

void solve() {

    cin >> a[1] >> a[2] >> a[3];

    cout << "First" << endl;
    
    rep(i, 1, 3) {

        if(a[i] == max({a[1], a[2], a[3]})) {

            int j = 1;

            if(i == 1) j = 2;

            cout << a[i] - a[j] << endl;

            cin >> x;

            a[x] += a[i] - a[j];

            if(x == 0) return ;

            else if(x == i) Go();

            else {

                if(a[x] > a[i]) Go();

                else {

                    cout << a[i] - a[j] << endl;

                    cin >> x;

                    a[x] += a[i] - a[j];

                    if(x == 0) return ;

                    else Go();

                }

            }

        }

    }

}


int main() {

//    int _; scanf("%d", &_);
//    while(_--) solve();

    solve();

    return 0;
}
原文地址:https://www.cnblogs.com/Willems/p/13329537.html