• AGC010D Decrementing


    题目链接

    先考虑有 (1) 的局面。显然每次操作只能将一个数减少 (1),若此时剩下的偶数的个数为奇数则先手必胜,反之后手必胜。

    这对正解有启发作用。下面对没有 (1) 的局面大力分情况讨论:

    1. 存在至少一个奇数并且偶数的数量为奇数个:先手必胜。先手只需维护任意时刻奇数个数 (geq 1),那么所有操作势必不能改变每个数的奇偶性,显然先手必胜。
    2. 存在大于一个奇数并且偶数的数量为偶数个:后手必胜。同上,先手不管怎么取都会变成情况 (1)
    3. 恰好存在一个奇数并且偶数的数量为偶数个:递归处理。先手显然只能把唯一的那个奇数减 (1),从而使得一些数的奇偶性改变来试图扭转战局。

    显然最后一种情况的次数是 (log) 级别的,可以暴力处理。时间复杂度 (O(nlogV))

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 100009;
    int n, a[N];
    
    void init()
    {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i++)
    		scanf("%d", &a[i]);
    }
    
    void work()
    {
    	if (n == 1)
    	{
    		if (a[1] == 1) puts("Second");
    		else puts("First");
    		return;
    	}
    	int qwq = 0;
    	while (1)
    	{
    		int flag = 0;
    		for (int i = 1; i <= n; i++)
    			if (a[i] == 1) { flag = 1; break; }
    		int tmp = 0, pos = -1;
    		for (int i = 1; i <= n; i++)
    			if (a[i] & 1)
    				tmp++, pos = i;
    		if (flag)
    		{
    			if (n - tmp + qwq & 1) puts("First");
    			else puts("Second");
    			return;
    		}
    		if (tmp > 1)
    		{
    			if (n - tmp + qwq & 1) puts("First");
    			else puts("Second");
    			return;
    		}
    		if (n - 1 & 1)
    		{
    			if (qwq) puts("Second");
    			else puts("First");
    			return;
    		}
    		a[pos]--;
    		int k = a[1];
    		for (int i = 2; i <= n; i++)
    			k = __gcd(k, a[i]);
    		for (int i = 1; i <= n; i++)
    			a[i] /= k;
    		qwq++;
    	}
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    shell脚本修改Linux系统中所有IP样例
    关闭并卸载数据库脚本
    查询编译不通过的存储过程并重新编译
    SQL函数造数据样例(一)
    类型转换和多态
    Java学习笔记(三)
    Java学习笔记二()
    Java学习笔记(一)
    1.2.零宽断言
    1.3.匹配小括号的字符(可能有小括号在一行的,也有多行的)
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13818393.html
Copyright © 2020-2023  润新知