“美登杯”上海市高校大学生程序设计邀请赛 **D. 小花梨的取石子游戏**
“美登杯”上海市高校大学生程序设计邀请赛 (华东理工大学)
D. 小花梨的取石子游戏
Description
小花梨有𝑜堆石子,第𝑗堆石子数量为𝑏𝑗,𝑜堆石子顺时针编号为1 − 𝑜(如图)。
游戏将进行 游戏将进行𝒏轮, 轮, 每轮游戏 单独进行 ,互不干扰 ,每轮初始时第 每轮初始时第𝒊 堆石子数目为𝒂𝒊。 。
第𝑗轮从编号为𝑗的那堆石子为起点,顺时针来取石子。两人轮流取石子,不可不取,最少取
一个石子,最多把当前这一堆取完,只有取完一堆后才走到下一堆石子。走完一圈后石子都
被取完,不能取石子的人就失败。假设两人以最优策略进行取石子操作,请分别输出𝑜轮游
戏是先手胜还是后手胜。
Input
第一行为正整数𝑜,表示石子的堆数 (1 ≤ 𝑜 ≤ 100000)
第二行输入𝑜个正整数表示每一堆的石子数目𝑏𝑗(1 ≤ 𝑏𝑗 ≤ 10 9 )
Output
输出𝑜行,第𝑗行表示第𝑗轮游戏的结果。如果先手胜则输出"𝐹𝑗𝑠𝑡𝑢",后手胜输出"𝑇𝑓𝑑𝑝𝑜𝑒"。
Example
Sample Input Sample Output
3
2 1 3
First
Second
First
2
2 2
First
First
Note
样例1:
游戏进行3轮
第11 2 32 1 3,先 第22 3 11 3 2,后 第3轮游戏石子堆下标的顺序为3 1 2,此时石子数目按顺序为3 2 1,先手胜
思路:
现在只考虑每一轮游戏
1.一堆的时候是必胜态
多堆的时候
起点数目大于1,是必胜态
因为可以取完或者取得只剩下一个,这两种状态的胜负一定同,也就是说一定可以到达必败态,所以此时为必胜态
若起点数目等于1,则和下一点的状态相反
那么我们可以先把a数组长度扩展为2倍(复制一遍在后面,因为要处理以每一个i为起始位置)从后向前维护一下1的连续个数即可。
当整个数组全为1的时候,特判n的奇偶出答案即可。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int a[maxn];
int n;
int b[maxn];
int flag=1;
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
cin>>n;
repd(i,1,n)
{
cin>>a[i];
a[i+n]=a[i];
}
for(int i=n*2;i>=1;--i)
{
if(a[i]==1)
{
b[i]=b[i+1]+1;
}else
{
b[i]=0;
flag=0;
}
}
if(flag)
{
repd(i,1,n)
{
if(!(n&1))
{
cout<<"Second"<<endl;
}else
{
cout<<"First"<<endl;
}
}
}else
{
repd(i,1,n)
{
if(!b[i])
{
cout<<"First"<<endl;
continue;
}
if(b[i]&1)
{
cout<<"Second"<<endl;
}else
{
cout<<"First"<<endl;
}
}
}
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
本博客为本人原创,如需转载,请必须声明博客的源地址。
本人博客地址为:www.cnblogs.com/qieqiemin/
希望所写的文章对您有帮助。