• Solution -「HNOI 2007」「洛谷 P3185」*游戏


    (mathcal{Description})

      Link.

      给定 (n) 堆石子,数量为 ({a_n}),双人博弈,每轮操作选定 (i<jle k),使 (a_i leftarrow a_i-1)(a_j leftarrow a_j+1)(a_k leftarrow a_k+1),并保证操作后所有 (a_ige0)。求保证先手胜的第一步操作方案数和字典序最小的第一步操作。

      多测,(nle21)(0le a_ile10^4),数据组数 (le10)

    (mathcal{Solution})

      由于每次只能取走一个石子,所以一个有 (x) 个石子的位置实际上可以看做 (x) 堆互不相关的石子放在同一个位置。而由于“互不相关”,求出每个位置上有一颗石子的 SG 函数异或起来就是答案。令 (operatorname{sg} (i)) 表示位置 (i) 有一颗石子的 SG 值,显然:

    [ operatorname{sg} (i)=operatorname{mex}_{i<jle k}{operatorname{sg} (j)oplusoperatorname{sg}(k)} ]

      扫出 (operatorname{sg}),设所有石子 (operatorname{sg}) 异或和为 (X),据此判断是否有解。若有解,暴力枚举第一次操作的 (i,j,k),若 (Xoplus operatorname{sg} (i)oplus operatorname{sg} (j)oplus operatorname{sg} (k)=0),说明操作后先手必败,此次操作计入贡献,最终 (mathcal O(Tn^3)) 就解决啦!

    (mathcal{Code})

    /* Clearink */
    
    #include <cstdio>
    #include <cstring>
    
    const int MAXN = 21;
    int n, sg[MAXN + 5], a[MAXN + 5];
    
    inline int calcSG ( const int i ) {
    	if ( ~sg[i] ) return sg[i];
    	bool vis[105] {};
    	for ( int j = i + 1; j <= n; ++ j ) {
    		for ( int k = j; k <= n; ++ k ) {
    			vis[calcSG ( j ) ^ calcSG ( k )] = true;
    		}
    	}
    	for ( int j = 0; ; ++ j ) if ( !vis[j] ) return sg[i] = j;
    }
    
    int main () {
    	int T;
    	for ( scanf ( "%d", &T ); T --; ) {
    		scanf ( "%d", &n ), memset ( sg, 0xff, sizeof sg );
    		int ans = 0;
    		for ( int i = 1; i <= n; ++ i ) {
    			if ( scanf ( "%d", &a[i] ), a[i] & 1 ) {
    				ans ^= calcSG ( i );
    			}
    		}
    		if ( !ans ) { puts ( "-1 -1 -1
    0" ); continue; }
    		int ways = 0;
    		for ( int i = 1; i <= n; ++ i ) {
    			if ( !a[i] ) continue;
    			for ( int j = i + 1; j <= n; ++ j ) {
    				for ( int k = j; k <= n; ++ k ) {
    					if ( !( ans ^ calcSG ( i ) ^ calcSG ( j ) ^ calcSG ( k ) ) && !ways ++ ) {
    						printf ( "%d %d %d
    ", i - 1, j - 1, k - 1 );
    					}
    				}
    			}
    		}
    		printf ( "%d
    ", ways );
    	}
    	return 0;
    }
    
  • 相关阅读:
    Fast Member
    C++箴言:理解typename的两个含义
    网上资源工具
    WeakReference
    MonoGame教程
    The RAII Programming Idiom
    OpenGL Common Mistakes
    Finalize()、Dispose()、SafeHandle、GC
    Interop with Native Libraries
    C++计算几何库
  • 原文地址:https://www.cnblogs.com/rainybunny/p/13752037.html
Copyright © 2020-2023  润新知