Poj1704:staircase nim【博弈】
题目大意:有一个无限长的一维的棋盘,棋盘上N个格子放置着棋子。两个人轮流操作,每次操作能选择其中一个棋子向左移动,但不能越过其它棋子或者两枚棋子放在同一格中,最后不能操作的人算输,问先手是否必胜?
思路:就是裸的阶梯博弈(staircase nim)方法也很简单。首先每个棋子能向右移动的距离是有限的,最多到前一个棋子处就停止了,比如第一个sample :1 2 3 每个棋子都不能移动就是 0 0 0 第二个sample: 1 5 6 7 9 12 14 17 就是0 3 0 0 1 2 1 2 这样每次移动一枚棋子向左n步,相当于把对应第二排的那个数据减去n,那个数据右边一个数加上n
这样问题就转变成了:有n堆石头,每次可以从一堆中拿出一些或全部石头给相邻的右边的一堆石头,或者最后一堆减去一些或全部石头,谁不能操作谁输,问先手是否必胜?
关于这个问题的结论和证明网上多如牛毛,结论是:假设从最后一堆石头开始与上一堆相间的石头数的异或和为P,P为0时先手必败反之必胜。比如a1,a2,a3,a4,a5 P的值就是a5 xor a3 xor a1
证明无非就是说明当不为平衡态时必然存在操作使局面进入平衡态,而局面已然是平衡态时任何操作都会破坏平衡。这里不再累述。说一下对这个问题的一些直观认识:为了叙述方便,可以把与最后一堆石头相间的石头称为有用堆(这里是我生造的一个词)而其它堆称为无用
堆。
□■□■□■□■□■□
如图空心方块表示有用堆,实心方块表示无用堆,显然把无用堆的石头放到有用堆的操作都是没有意义的,因为这次从无用堆放进多少块石头到有用堆,下一次操作就能将这些运进来的石头扔给下一个无用堆或者扔掉(最后一堆石头),而有用堆石头的序列分毫未变,因此只需看有用堆的石头情况即可。而有用堆的石头放进无用堆相当于扔掉的操作,因为刚才已经证明无用堆中的石头是不起作用毫无意义的,这样就将问题化为了有用堆的NIM游戏!!因此只需计算有用堆的异或和就能计算出先手的胜负情况
//poj1704
#include<cstdio>
#include<string.h>
#include<iostream>
using namespace std;
int a[1009]={0};
void qsort(int l,int r)
{
int i=l,j=r,mid=a[(l+r)>>1],temp;
while(i<j)
{
while(a[i]<mid)i++;while(a[j]>mid)j--;
if(i<=j)
{
temp=a[i];a[i]=a[j];a[j]=temp;
i++;j--;
}
}
if(i<r)qsort(i,r);
if(l<j)qsort(l,j);
}
int main()
{
int n,t,chess[1009]={0};
scanf("%d",&t);
while(t--)
{
int x=0,last=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
qsort(1,n);
for(int i=1;i<=n;i++)
{
chess[i]=a[i]-last-1;
last=a[i];
}
for(int i=n;i>=1;i=i-2)
x=x^chess[i];
if (x!=0)printf("Georgia will win\n");else printf("Bobwill win\n");
}
return 0;
}
调试小结:3次WA 原因:未看清棋子顺序不是从小到大!!
Poj1704:staircase nim【博弈】的更多相关文章
- POJ1704 Georgia and Bob(Nim博弈变形)
Georgia and Bob Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14312 Accepted: 4840 ...
- Nim博弈&&POJ1704
Nim博弈 题目 有n堆物品,两人轮流取,每次取某堆中不少于1个,先取完者胜. 分析 经典问题,该问题的策略也成为了许多问题的基础. 要判断游戏的胜负只需要异或运算就可以了,有以下结论: $a_1 \ ...
- HDU 2509 Nim博弈变形
1.HDU 2509 2.题意:n堆苹果,两个人轮流,每次从一堆中取连续的多个,至少取一个,最后取光者败. 3.总结:Nim博弈的变形,还是不知道怎么分析,,,,看了大牛的博客. 传送门 首先给出结 ...
- HDU 1907 Nim博弈变形
1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...
- zoj3591 Nim(Nim博弈)
ZOJ 3591 Nim(Nim博弈) 题目意思是说有n堆石子,Alice只能从中选出连续的几堆来玩Nim博弈,现在问Alice想要获胜有多少种方法(即有多少种选择方式). 方法是这样的,由于Nim博 ...
- hdu 1907 John&& hdu 2509 Be the Winner(基础nim博弈)
Problem Description Little John is playing very funny game with his younger brother. There is one bi ...
- 【POJ】1704 Georgia and Bob(Staircase Nim)
Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...
- 关于NIM博弈结论的证明
关于NIM博弈结论的证明 NIM博弈:有k(k>=1)堆数量不一定的物品(石子或豆粒…)两人轮流取,每次只能从一堆中取若干数量(小于等于这堆物品的数量)的物品,判定胜负的条件就是,最后一次取得人 ...
- HDU - 1850 Nim博弈
思路:可以对任意一堆牌进行操作,根据Nim博弈定理--所有堆的数量异或值为0就是P态,否则为N态,那么直接对某堆牌操作能让所有牌异或值为0即可,首先求得所有牌堆的异或值,然后枚举每一堆,用已经得到的异 ...
随机推荐
- RHEL6.5---LVS(IP-TUN)
实验环境: 主机名 IP 所需软件 master eth0==>192.168.30.160(RIP) eth0:1==>192.168.30.130(VIP) ipvsadm node ...
- springboot 配置Ehcache
Ehcache的基本配置说明我就不说了.小编记录一下在springboot中使用Ehcache的使用方法. 第一步:在classpath下引入配置文件ehcache.xml 代码如下: <ehc ...
- Android提供的对话框
1.普通对话框: 给出提示信息,有yes.no两个按钮. AlertDialog dialog=new AlertDialog.Builder(this) //this代表当前Activity对象,表 ...
- C++模板类头文件和实现文件分离
http://www.cnblogs.com/lvdongjie/p/4288373.html 如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer ...
- ArrayList不同循环方式
一: ArrayList<String> list = new ArrayList<String>(); list.add("1"); list.add ...
- 【整理】iview Tree数据格式问题,无限递归树处理数据
iview Tree数据格式问题,无限递归树处理数据 https://juejin.im/post/5b51a8a4e51d455d6825be20
- app自动化配置信息
caps={ "platformName":"Android",#平台名称 "platformVersion":"6. ...
- python基础一 day2 数据类型
int: bool: 类型转换: str到int有条件,str必须是数字, "123e"是错误的 bool转换为int类型,需要int(x) 结果: 结果: 空字 ...
- ubuntu卡机
卡机了用ctrl+alt+t打开终端然后top看后台程序 最后kill -9 + PID就能把最影响问题的程序杀掉 我之前就杀了一个占100%cpu的程序
- 尺取法 || emmmm
给定两个上升的数组,一个数组任取一个数,求两个数差的min 尺取法emm 也不知道对不对 #include <stdio.h> #include <stdlib.h> #def ...