小花梨的取石子游戏
题目描述
小花梨有n堆石子,第i堆石子数量为ai,n堆石子顺时针编号为1−n(如图)。
游戏将进行n轮,每轮游戏单独进行,互不干扰,每轮初始时第i堆石子数目为ai。
第i轮从编号为i的那堆石子为起点,顺时针来取石子。两人轮流取石子,不可不取,最少取一个石子,最多把当前这一堆取完,只有取完一堆后才走到下一堆石子。走完一圈后石子都被取完,不能取石子的人就失败。假设两人以最优策略进行取石子操作,请分别输出n轮游戏是先手胜还是后手胜。
输入
第一行为正整数n,表示石子的堆数(1≤n≤100000)
第二行输入n个正整数表示每一堆的石子数目ai(1≤ai≤109)
输出
输出n行,第i行表示第i轮游戏的结果。如果先手胜则输出"First",后手胜输出"Second"。
样例输入
3
2 1 3
样例输出
First
Second
First
提示
游戏进行3轮
第1轮游戏石子堆下标的顺序为1 2 3,此时石子数目按顺序为2 1 3,先手胜
第2轮游戏石子堆下标的顺序为2 3 1,此时石子数目按顺序为1 3 2,后手胜
第3轮游戏石子堆下标的顺序为3 1 2,此时石子数目按顺序为3 2 1,先手胜
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6;
int main()
{
int a[MAX+5],sum[MAX+5],n;
scanf("%d",&n);
int flag=0,ans=0,cnt=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(flag==0&&a[i]!=1){
flag=1;
}
if(flag==0){
a[n+i]=a[i];
ans++;
}
if(a[i]!=1){
cnt++;
}
}
if(n==1){
printf("First
");
}else{
if(flag==0){
for(int i=0;i<n;i++){
if(n%2!=0){
printf("First
");
}else{
printf("Second
");
}
}
}else{
if(cnt==n){
for(int i=0;i<n;i++){
printf("First
");
}
}else{
int n1=n;
n+=ans;
ans=0;
int sum1[MAX+5];
for(int i=n-1;i>=0;i--){
if(a[i]==1&&a[i+1]==1){
sum1[ans]=sum1[ans-1]+1;
ans++;
}else if(a[i]==1&&a[i+1]!=1){
sum1[ans++]=1;
}
}
int Count=0;
if(a[0]==1){
for(int i=ans-1;i>=sum1[ans-1];i--){
sum[Count++]=sum1[i];
}
}
else{
for(int i=ans-1;i>=0;i--){
sum[Count++]=sum1[i];
}
}
n=n1,ans=0;
for(int i=0;i<n;i++){
flag=0;
if(a[i]==1){
if(sum[ans]%2!=0){
flag=1;
}
ans++;
}
if(flag==0){
printf("First
");
}
else{
printf("Second
");
}
}
}
}
}
return 0;
}