题目:http://acmoj.shu.edu.cn/problem/418/
素数筛一边,二维sg先预处理出sg值,然后O(1)查询
- 如果一个点能够走到必败点,那它就是必胜点
- 如果一个点走不到必败点,只能走到必胜点,这个点就是必败点
1必胜,2必败
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=10000+10,maxn=500+100,inf=0x3f3f3f; bool vis[N]; int prime[N],cnt,sg[maxn][maxn]; void getprime() { cnt=0; memset(vis,1,sizeof vis); for(int i=2;i<N;i++) { if(vis[i]) { prime[cnt++]=i; for(int j=2*i;j<N;j+=i) vis[j]=0; } } } void getsg(int n) { memset(sg,0,sizeof sg); sg[1][1]=2; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(sg[i][j]==0)sg[i][j]=2; if(sg[i][j]==2) { for(int k=0;;k++) { int nx=prime[k]+i,ny=prime[k]+j; if(nx>n&&ny>n)break; if(nx<=n)sg[nx][j]=1; if(ny<=n)sg[i][ny]=1; if(nx<=n&&ny<=n)sg[nx][ny]=1; } } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); getprime(); getsg(500); int t,n,m; cin>>t; while(t--){ cin>>n>>m; if(sg[n][m]==1)cout<<"Sora"<<endl; else cout<<"Shiro"<<endl; } return 0; }