博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bzoj4600--Sdoi2016硬币游戏
阅读量:4964 次
发布时间:2019-06-12

本文共 2899 字,大约阅读时间需要 9 分钟。

题意 :

Description

Alice和Bob现在在玩的游戏,主角是依次编号为1到n的n枚硬币。每一枚硬币都有两面,我们分别称之为正面和反
面。一开始的时候,有些硬币是正面向上的,有些是反面朝上的。Alice和Bob将轮流对这些硬币进行翻转操作,且
Alice总是先手。具体来说每次玩家可以选择一枚编号为x,要求这枚硬币此刻是反面朝上的。对于编号x来说,我
们总可以将x写成x=c*2^a*3^b,其中a和b是非负整数,c是与2,3都互质的非负整数,然后有两种选择第一种,选择
整数p,q满足a>=p*q,p>=1且1<=q<=MAXQ,然后同时翻转所有编号为c*2^(a-p*j)*3^b的硬币,其中j=0,1,2,..,q。第
二种,选择整数p,q满足b>=p*q,p>=1且1<=q<=MAXQ,然后同时翻转所有编号为c*2^a*3^(b-p*j)的硬币,其中j=0,1,
2,..,q。可以发现这个游戏不能不先进行下去,当某位玩家无法继续操作上述操作时,便输掉了游戏。作为先手的
Alice,总是希望可以在比赛开始之前就知道自己能否获胜。她知道自己和Bob都是充分聪明的,所以在游戏过程中
两人都会最优化自己的策略并尽量保证自己处于不败的情形中

Input

本题有多组测试数据,第一行输入一个整数T,表示总的数据组数。之后给出T组数据
每组数据第一行输入两个整数n,MAXQ
第二行输入n个整数,第i个数表示第i个硬币的初始状态,0表示反面朝上,1表示正面朝上
对于100%的数据1<=n<=30000,1<=MAXQ<=20,t<=100。

Output

输出共有t行。对于每一组数据来说,如果Alice先手必胜,则输出"win"(不包括引号),否则输出"lose"
 
------------------------------------------------此后一千里---------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
考虑每一个编号为x的硬币翻动的sg值,那么这个sg值显然只与x中2,3的因子个数相关,因为c不同的硬币互相之间不影响。
那么我们设定sg[i][j]为x=c*2^i*3^j的硬币翻动的sg值,那么转移可以去暴力枚举后继局面,即我们去枚举去2的因子,和去3的因子,那么能够达到的后继局面sg值就是所有枚举到的后继状态的异或和。
然后对于给出局面就可以直接计算sg值了。
又涨了新的博弈姿势,发现博弈姿势永远涨不完。。。
ps :调了半天错发现自己一直以为1是能翻的,0是不能翻的。。。。
代码 :
/*Lelouch vi Britannia here commands you , all of you , die !*/#include
#define INF 0x3f3f3f3f#define low(x) ((x)&(-(x)))#define LL long long#define eps 1e-9using namespace std;#define int intinline int Max(int a,int b) {
return a>b?a:b;}inline int Min(int a,int b) {
return a
0?a:-a;}inline int Sqr(int a) {
return a*a;}#undef intint sg[22][22][22];bool go[100];int two[30005],three[30005];void Pre(int n) { int mxq,i,j,p,q,s,k; for(mxq=1;mxq<=20;mxq++) { for(i=0;i<=20;i++) for(j=0;j<=20;j++) { for(p=1;p<=i;p++) for(q=1;q<=mxq&&p*q<=i;q++) { for(s=-1,k=1;k<=q;k++) s=s==-1?sg[mxq][i-p*k][j]:s^sg[mxq][i-p*k][j]; if(~s) go[s]=1; } for(p=1;p<=j;p++) for(q=1;q<=mxq&&p*q<=j;q++) { for(s=-1,k=1;k<=q;k++) s=s==-1?sg[mxq][i][j-p*k]:s^sg[mxq][i][j-p*k]; if(~s) go[s]=1; } for(s=0;true;s++) if(!go[s]) { sg[mxq][i][j]=s;break; } memset(go,0,sizeof(go)); } } for(int i=1;i<=n;i++) { two[i]=i%2?0:two[i/2]+1; three[i]=i%3?0:three[i/3]+1; }}int T,n,maxq,ans;int main() { scanf("%d",&T); Pre(30000); while(T--) { ans=0; scanf("%d%d",&n,&maxq); for(int a,i=1;i<=n;i++) { scanf("%d",&a); if(!a) ans^=sg[maxq][two[i]][three[i]]; } ans!=0?puts("win"):puts("lose"); } return 0;}/*Hmhmhmhm . Yes , I am killer.*/
View Code

 

转载于:https://www.cnblogs.com/ihopenot/p/6581944.html

你可能感兴趣的文章
java if 用法详解_Java编程中的条件判断之if语句的用法详解
查看>>
kafka的java客户端_KAFKA Producer java客户端示例
查看>>
java -f_java学习笔记(一)
查看>>
java 什么题目好做_用java做这些题目
查看>>
java中的合同打印_比较方法违反了Java 7中的一般合同
查看>>
php 位运算与权限,怎么在PHP中使用位运算对网站的权限进行管理
查看>>
php include效率,php include类文件超时
查看>>
matlab sin函数 fft,matlab的fft函数的使用教程
查看>>
wcdma下行如何解扩解扰 matlab,WCDMA技术基础.ppt
查看>>
MySQL date_format() 函数
查看>>
mysql 时间处理
查看>>
mysql adddate()函数
查看>>
mysql addtime() 函数
查看>>
mysql 根据日期时间查询数据
查看>>
mysql 创建时间字段
查看>>
mysql 生成随机数rand()
查看>>
mysql e的n次幂exp()
查看>>
mysql sin() 函数
查看>>
mysql upper() 函数
查看>>
mysql 子查询
查看>>