zoukankan      html  css  js  c++  java
  • 洛谷 [P2594] 染色游戏

    博弈论+SG函数的应用

    这是一个二维翻硬币问题

    一维翻硬币问题有一个结论:

    局面的SG值等于局面中所有反面朝上的硬币单独存在时的SG值的异或和

    这个结论同样适用于二维的翻硬币问题

    证明可以用数学归纳法,这里省去(其实是我不会证)

    那么如何求每个硬币单独反面朝上时的SG值,首先考虑递推

    然而不会推

    那就只好打表找规律

    有如下规律:

    [SG(i, j) = egin {cases} lowbit(i + j - 1), quad i == 1 || j == 1\ 2 ^{ i + j - 2}, quad i != 1 &&j != 1 end{cases} ]

    我们发现SG函数值最大可达 2 的 200 次方,无法用long long 储存

    我们可以用 bool 数组 或 bitset 来模拟

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int T, sg[105][105], n, m, a[10005], cnt, mp[1200];
    bool f[300];
    int lowbit(int x) {
    	return x & (-x);
    }
    int getsg(int a, int b){
    	if(a == 1 || b == 1){
    		return mp[lowbit(a + b - 1)];
    	}else return a + b - 2;
    }
    int main() {
    	for(int i = 0 ; i <=9 ; i++) {
    		mp[(1<<i)] = i;
    	}
    	cin>>T;
    	while(T--) {
    		memset(f, 0, sizeof(f));
    		cin>>n>>m;
    		int ans = 0;
    		for(int i = 1 ; i <= n ; i++) {
    			for(int j = 1 ; j <= m ; j++) {
    				char c ;
    				scanf(" %c ", &c);
    				if(c !='H'){
    					f[getsg(i, j)] ^= 1;
    				}
    			}
    		}
    		for(int i = m + n - 1 ; i >= 0 ; i--) if(f[i]) {ans = 1;break;}
    		if(ans) printf("-_-
    ");
    		else printf("=_=
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Callback2.0
    设计模式之Composite
    设计模式之Proxy
    React Native DEMO for Android
    React Native 与 夜神模拟器的绑定
    Skipping 'Android SDK Tools, revision 24.0.2'; it depends on 'Android SDK Platform-tools, revision 20' which was not installed.
    .ui/qrc文件自动生成.py文件
    简单排序算法
    Big O
    设计模式之Adapter
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8509330.html
Copyright © 2011-2022 走看看