[博弈论]洛谷P4018P4860(有向图游戏的和)
作者:互联网
https://www.luogu.com.cn/problem/P4018
题意:
思路:
因为数据范围巨大,所以猜是个规律题。
先写个平淡的有向图游戏的和,然后打表!
代码:
int t,n,m;
int primes[N],cnt;
bool st[N];
int sg[110];
void get(){//线性筛
for(int i=2;i<N;i++){
if(!st[i]) primes[cnt++] = i;
for(int j=0;primes[j] < N/i;j++){
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
int dfs(int x){
if(sg[x] != -1) return sg[x];
if(x == 0) return sg[x] = 0;
int vis[110];
memset(vis,0,sizeof vis);
vis[dfs(x-1)] = 1;
for(int i=0;i<cnt && primes[i] <= x;i++){
int t = primes[i];
while(t <= x){
vis[dfs(x - t)] = 1;
t *= primes[i];
}
}
for(int i=0;;i++)
if(!vis[i]) return sg[x] = i;
}
int main(){
memset(sg,-1,sizeof sg);
get();
for(int op=1;op<=100;op++){
int n = op;
if(dfs(n)) printf("%d 1\n",op);
else printf("%d 0\n",op);
}
return 0;
}
可以观察到,6的倍数则先手输,不是则先手赢
可以看下洛谷题解的推理
类似的题目P4860
只要把中间的代码稍微改一下,打表就可以看出来,4的倍数
vis[dfs(x-1)] = 1;
for(int i=0;i<cnt && primes[i] <= x;i++){
int t = primes[i];
vis[dfs(x - t)] = 1;
}
标签:有向图,洛谷,游戏,int,P4018P4860,打表,倍数 来源: https://www.cnblogs.com/dtdbm/p/14966364.html