P1857 质数取石子
题目描述
桌上有若干个石子,每次可以取质数个。谁先取不了,谁就输。问最少几步能赢?(一个人取一次算一步)假设双方都使用最优策略,且必胜方会尽量快地取胜,必败方会尽可能拖延步数。
输入格式
第一行 NNN,表示有 NNN 组数据
接下来 NNN 行为石子数
输出格式
每组数据一个数,若必胜,则输出最少步数,否则输出 −1-1−1。
输入输出样例 #1
输入 #1
3
8
9
16
输出 #1
1
-1
3
说明/提示
石子数 ≤20000\leq 20000≤20000,N≤10N\leq 10N≤10
C++实现
#include<bits/stdc++.h>
using namespace std;
int a[20010],h[10000],f[20010],cnt=0,k[20010];
void ss(int n)//线性筛模板
{
memset(a,1,sizeof(a));
a[1]=0;
for(int i=2;i<=n;i++) {
if(a[i])h[++cnt]=i;
for(int j=1;j<=cnt&&i*h[j]<=n;j++)
{
a[i*h[j]]=0;
if(i%h[j]==0)break;
}
}
}
int main()
{
ss(20000);
f[0]=f[1]=-1;//初始化 F
for(int i=2;i<=20000;i++)
{
int s=-1,c=0,d=99999;//c 为最小值,d 为最大值
for(int j=1;j<=6000;j++)
{
if(i>=h[j]&&f[i-h[j]]==-1){s=1;d=min(d,k[i-h[j]]+1);}//最小值更新
else if(i>=h[j]&&f[i-h[j]]!=-1)c=max(c,k[i-h[j]]+1);//最大值更新
}
f[i]=s;
if(s==-1)k[i]=c;
else k[i]=d;
}
int t;
cin>>t;
while(t--)
{
int e;
cin>>e;
if(f[e]==1)cout<<k[e]<<'\n';
else cout<<f[e]<<'\n';
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
用C++实现信奥 P1857 质数取石子&spm=1001.2101.3001.5002&articleId=155659934&d=1&t=3&u=c3d028712b3c4194a7cc4bc0f6a35c13)
355

被折叠的 条评论
为什么被折叠?



