階梯博弈

模型:在下標爲0-n的(n+1)堆石子中,每次可以在非空的一堆中選擇一個或多個石子扔到前一堆石子中,第0堆石子不能再扔了,即第1堆石子可以扔到第0堆,但第0堆的石子不能動,所以最後的狀態一定是第0堆放着原先所有堆的石子。若誰不能移動石子則輸。

當且僅當所有奇數編號堆的石子數的異或和不爲0時,先手必勝。

例如
在這裏插入圖片描述
地面是第0堆,則ans=a[1]^ a[3] ^ a[5]=2^ 3 ^ 4=5!=0,
所以先手必勝。

驚奇隊長和滅霸的決戰

題目

驚奇隊長獲得了驚人的超能力後打算與滅霸決一死戰,打敗滅霸來維護世界和平(能力越大,責任越大,23333),於是他們約在了一個不知名的星球,奇怪的是這個星球是一個階梯狀的星球,從第一層一直到第K層可以看成是一個K層的階梯,並且每一層只能放一個人。由於星球比較小,許多人慕名而來,導致星球極爲堵塞,後來的人無法走上樓梯來觀看決戰。該星球管理員AA和星球管理員BB爲了讓更多的人來到這個星球觀看這場戰鬥,於是打算把這些人排隊。現在有nn個人在階梯上擁擠着,管理員可以使任何一個人向上走多個臺階,但如果高階臺階上有人,你會被擋在它的下一個臺階上。兩個人或者兩個以上不能共用同一臺階,也不能向下臺階走。管理員A,BA,B輪流發號指令,如果管理員不能再本輪使任和人發生改變,那麼該管理員認輸。現在已知每個人所在的位置,請你計算先手管理員第一步如何決策能勝出。

輸入描述
輸入數據爲一行用空格分開的nn個整數,表示每個人的位置。臺階序號從11算起,所以最後一個人的位置即是臺階的總數。(n<100, 臺階總數<1000)
輸出描述
輸出爲一行兩個整數:AB: A B, 表示先手第一次把AA位置的人移動到BB位置上。若有多個解,輸出AA值較小的解,若無解則輸出1-1
樣例輸入 1
1 5 9
樣例輸出 1
1 4
樣例輸入 2
1 5 8 10
樣例輸出 2
1 3

思路:可以看作階梯博弈,石子數爲兩個人階梯之差減去1,因爲當一個人上樓梯時,可轉化爲將石子轉移的過程。
注意輸出的位置是第幾個樓梯,而不是第幾個人。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX_N=1010;
int a[MAX_N];
int b[MAX_N];
int main(void){
	int n=0,i,x;
	while(scanf("%d",&x)!=EOF){
		b[++n]=x;
	}
	sort(b+1,b+n+1);
	int ans=0;
	for(i=1;i<n;i++){
		a[i]=b[i+1]-b[i]-1;
		if(i%2==1)
		ans^=a[i];
	}
	if(!ans){
		printf("-1\n");
	}
	else{
		for(i=1;i<n;i+=2){
			if(a[i]>(ans^a[i])){
				printf("%d %d\n",b[i],b[i]+a[i]-(ans^a[i]));
				break;
			}
			else{
				if(a[i+1]+a[i]>=(ans^a[i])){
					printf("%d %d\n",b[i+1],b[i+1]+a[i+1]-(a[i+1]+a[i]-(ans^a[i])));
					break;
				}
			}
		}
	}
	return 0;
}
發佈了62 篇原創文章 · 獲贊 6 · 訪問量 1952
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章