CSP赛前集训 【板刷CF】

板刷CF

题目描述:(暂不提供)

博弈论我学的一 q i o qio qio不同。
(我很想知道为什么题设里的人绝顶聪明但我却还要帮他们看?

这道题分情况讨论:

1. 1. 1. 如果 a a a中出现了 1 1 1,那么很显然就可以判断剩下的数的奇偶性对不对?
(就是你拿一个我拿一个
2. 2. 2. 在非 1 1 1的基础上,如果剩下的数和为奇数,那么先手也必胜。
(这样的话至少有一个奇数,而且在到我选的时候剩余的奇偶性还是不变。这样的话就必胜
3. 3. 3. 在非 1 1 1和非 2 2 2的基础上,如果剩余有 1 1 1个以上的奇数,那么先手必败。
(也就是说当前剩下总和为偶数,且其中没有 1 1 1,由于有一个以上的奇数,所以你无法改变下一次到你手中的奇偶性

然后判断完上面所述后你剩下的总和为偶数,且上一次剩余中有一个奇数。
然后就只能往下递归啦。

#include 
#include 
using namespace std;

const int N = 100010;
const int INF = 0x3f3f3f3f;

inline int min(int a,int b) { return a < b ? a : b; }

int n,a[N];

int gcd(int a,int b) { return b ? gcd(b,a % b) : a; }

int dfs(int x)
{
    int ret = 0,mn = INF,fg = 0,g = 0;
    for(int i = 1;i <= n; ++ i) 
        ret += a[i] - 1, fg += a[i] % 2, mn = min(mn,a[i]);
    if(mn == 1) return ret % 2;
    if(ret % 2) return 1;
    if(fg > 1) return 0;
    for(int i = 1;i <= n; ++ i) if(a[i] % 2) --a[i]; g = a[1];
    for(int i = 2;i <= n; ++ i) { g = gcd(g,a[i]); if(g < 2) break; }
    for(int i = 1;i <= n; ++ i) a[i] /= g;
    return dfs(x + 1);
}

int main()
{
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);

    scanf("%d",&n);
    for(int i = 1;i <= n; ++ i) scanf("%d",&a[i]);

    dfs(1) ? printf("First") : printf("Second");
    fclose(stdin); fclose(stdout);
    return 0;
}

Z J J ZJJ ZJJ考场 A C AC AC,真是太 T M ^{TM} TM l i a o liao liao啊。

你可能感兴趣的:(CSP赛前集训,好题)