Good Luck in CET-4 Everybody!
大學英語四級考試就要來臨了,你是不是在緊張的複習?也許緊張得連短學期的ACM都沒工夫練習了,反正我知道的Kiki和Cici都是如此。當然,作爲在考場浸潤了十幾載的當代大學生,Kiki和Cici更懂得考前的放鬆,所謂“張弛有道”就是這個意思。這不,Kiki和Cici在每天晚上休息之前都要玩一會兒撲克牌以放鬆神經。
“升級”?“雙扣”?“紅五”?還是“鬥地主”?
當然都不是!那多俗啊~
作爲計算機學院的學生,Kiki和Cici打牌的時候可沒忘記專業,她們打牌的規則是這樣的:
1、 總共n張牌;
2、 雙方輪流抓牌;
3、 每人每次抓牌的個數只能是2的冪次(即:1,2,4,8,16…)
4、 抓完牌,勝負結果也出來了:最後抓完牌的人爲勝者;
假設Kiki和Cici都是足夠聰明(其實不用假設,哪有不聰明的學生~),並且每次都是Kiki先抓牌,請問誰能贏呢?
當然,打牌無論誰贏都問題不大,重要的是馬上到來的CET-4能有好的狀態。
Good luck in CET-4 everybody!
題解
可以說是SG函數的模板題了,首先求出所有2的冪作爲取數數組,然後依次求出每個數的SG函數值,若SG函數值爲0,說明此狀態是必敗態,若不爲0,則代表着第一次應該取的數字,先手的人取SG函數值個時,就讓後手的人陷入必敗態
代碼
#include<iostream>
#include<cstring>
using namespace std;
const int Maxm=1010,Maxn=10;
int f[15],sg[Maxm];
bool Hash[Maxm];
void Getsg()
{
f[0]=1;
for(int i=1;i<=10;i++){
f[i]=f[i-1]<<1;
}
for(int i=1;i<Maxm;i++){
//cout<<"i:"<<i<<endl;
memset(Hash,false,sizeof(Hash));
for(int j=0;j<=10&&f[j]<=i;j++){
Hash[sg[i-f[j]]]=true;
//cout<<sg[i-f[j]]<<' ';
}
//cout<<endl;
for(int j=0;j<=i;j++){
if(!Hash[j]){
sg[i]=j;
//cout<<j<<endl;
break;
}
}
}
}
int main()
{
Getsg();
int m;
while(scanf("%d",&m)==1){
if(sg[m]!=0){
cout<<"Kiki"<<endl;
}
else{
cout<<"Cici"<<endl;
}
}
}