• Codeforces 142D(博弈)


    要点

    • 不难发现问题转化成:n堆石子,每次最多选k堆最少选1堆然后拿走一个石子,谁先没子可拿谁败。本题中撤退不必考虑。
    • 就是记笔记吧,类似nim的博弈,举例:$$k=3,n=4$$$$4堆石子分别是1、2、3、3$$全化为二进制$$01$$$$10$$$$11$$$$11$$然后每一位纵向加和,两位都是(3\%(k+1)==0),全能整除((k+1))则后手胜,否则都是先手胜。PS:我只知道(k+1)应该与那个经典益智问题有关:共有若干火柴,每次最少拿1最多拿k,怎样先手必胜。
    int n, m, k;
    char s[105];
    int ans, val[105];
    bool flag1, flag2;
    
    int main() {
    	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    	cin >> n >> m >> k;
    	rep(i, 1, n) {
    		cin >> s;
    
    		val[i] = -1;
    		int f1 = -1, f2 = -1, tmp = 0;
    		rep(j ,0, m - 1)
    			if (s[j] == 'G')	f1 = j;
    			else if (s[j] == 'R')	f2 = j;
    			else	tmp++;
    
    		if (tmp == 0 || tmp == m)	continue;
    		if (f1 >= 0 && f2 >= 0) {
    			val[i] = abs(f2 - f1) - 1;
    		} else if (f1 < 0) {
    			flag2 = 1;
    		} else	flag1 = 1;
    	}
    	if (!flag1 && !flag2) {
    		int tmp[10] = {0};
    		rep(i, 1, n)
    			if (val[i] > 0) {
    				int cnt = 0;
    				for (int j = val[i]; j; j >>= 1)
    					tmp[cnt++] += j % 2;
    			}
    		rep(i, 0, 9)
    			if (tmp[i] % (k + 1) != 0) {
    				flag1 = 1;
    			}
    		cout << (flag1 ? "First
    " : "Second
    ");
    	} else if (flag1 && flag2) {
    		cout << "Draw
    ";
    	} else	cout << (flag1 ? "First
    " : "Second
    ");
    	return 0;
    }
    
  • 相关阅读:
    行为科学统计第一章知识点总结
    JVM垃圾回收参数说明整理
    RestTemplate
    SparkContext源码阅读
    Spark RDD类源码阅读
    Scala学习笔记
    JAVA虚拟机类型转换学习
    工程开发实用类与方法总结(未完)
    JAVA 几种引用类型学习
    JAVA虚拟机垃圾回收算法原理
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/11123888.html
Copyright © 2020-2023  润新知