B. Sequential Nim
题意
nim博弈的简化版,要求只能从第一堆开始取。最后取得胜利
思路
从后往前推,第n堆是必胜态,第n-1堆以及以前,如果只有1个石子,状态转换,如果多于一个石子,必胜(因为可以留一个也可以一个不留)。
代码
int a[100005];
main(void)
{
int t=read();
while(t--)
{
int n=read();
int ans=0;
for(int i=1;i<=n;i++)
{
a[i]=read();
}
int flag;
for(int i=n;i>=1;i--)
{
if(i==n)
{
flag=1;
continue;
}
if(flag==1&&a[i]==1)
{
flag=0;
}
else if(flag==0&&a[i]==1)
{
flag=1;
}
if(a[i]>=2)
{
flag=1;
}
}
if(flag==1)
{
printf("First
");
}
else
{
printf("Second
");
}
}
}
C1. Prefix Flip
题意:
给定两个字符串a,b,将a的前i位取反然后翻转,使之变为b。
分析:
因为不要求最小的步骤,但是时间上复杂度要小于 (n^2),考虑简化过程,现将a变为全0或者全1
再将b变为全0或者全1,然后a的步骤正序输出,b的步骤倒序输出即可
代码
char a[1005],b[1005],c[1005];
main(void)
{
int t=read();
while(t--)
{
int n=read();
scanf("%s",a+1);
scanf("%s",b+1);
for(int i=1;i<=n;i++)
{
c[i]=a[i];
}
int p=n;
vector<int >q;
while(p)
{
if(a[1]!=b[p])
{
q.push_back(p);
for(int i=1;i<=p;i++)
{
if(c[p-i+1]=='1')
a[i]='0';
else a[i]='1';
}
}
else
{
q.push_back(1);
if(a[1]=='0')a[1]='1';
else a[1]='0';
c[1]=a[1];
q.push_back(p);
for(int i=1;i<=p;i++)
{
if(c[p-i+1]=='1')
a[i]='0';
else a[i]='1';
}
}
p--;
for(int i=1;i<=n;i++)
{
c[i]=a[i];
}
}
int l=q.size();
printf("%d",l);
for(int i=0;i<l;i++)
{
printf(" %d",q[i]);
}
printf("
");
}
}