Uva 1378 A Funny Stone Game

vjudge上的UVA题面都不好复制。。。

首先可以发现,每次操作可以从任意堆取一颗石子(除了最后一堆),然后把这颗石子变成两个然后放到这堆后面的任意两堆里去。

而且每次操作最多可以取一个石子。

这样我们就把每个石子看成一个子游戏,位置在i的堆的每个石子看成一个石子数为n-i的堆。

然后再搞一搞sg函数,这题就出来了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define maxn 30
using namespace std;
int sg[105],n,m,T;
int v[1005],k,p,o;
int a[105],ans;

inline void init(){
	sg[0]=0;
	for(int i=1;i<=maxn;i++){
		int now=0;
		for(int j=0;j<i;j++)
		    for(int u=0;u<=j;u++) v[sg[j]^sg[u]]=i;
		while(v[now]==i) now++;
		sg[i]=now;
//		printf("%d %d
",i,sg[i]);
	}
}

int main(){
	init();
	int tot=0;
	while(scanf("%d",&n)==1&&n){
		ans=0,tot++;
		for(int i=1;i<=n;i++) scanf("%d",a+i);
		for(int i=1;i<=n;i++) if(a[i]&1) ans^=sg[n-i];
		
		printf("Game %d: ",tot);
		if(!ans) puts("-1 -1 -1");
		else{
			bool flag=0;
			for(int i=1;i<=n;i++) if(a[i]){
			    for(int j=i+1;j<=n;j++){
			        for(int u=j;u<=n;u++)
			        	if((sg[n-i]^sg[n-j]^sg[n-u])==ans){
			        		printf("%d %d %d
",i-1,j-1,u-1);
			        		flag=1;
			        		break;
						}
					if(flag) break;
				}
				if(flag) break;
			}
		}
	}
	
	return 0;
}

  

原文地址:https://www.cnblogs.com/JYYHH/p/8419311.html