http://acm.hdu.edu.cn/showproblem.php?pid=1536
计算sg值。
注意两个地方:
1. s是无序的。
2. 不能对n=10000打表,因为能取的个数是给定的,会有打不到的点。
code:
#include<cstdio>
#include<cstring>
int s[101], sg[10001], k ;
int mex(int n){
if(sg[n]!=-1) return sg[n] ;
bool vis[101] ;//n最多有100个后继
int i ;
memset(vis, false, sizeof(vis)) ;
for(i=0; i<k; i++){
if(s[i]>n) continue ;//不能break, s无序
sg[n-s[i]] = mex(n-s[i]) ;
vis[sg[n-s[i]]] = true ;
}
for(i=0; vis[i]; i++) ;
sg[n] = i ;
return sg[n] ;
}
int main(){
int m, l, i, j, t, sum ;
while(~scanf("%d", &k)&&k){
for(i=0; i<k; i++)
scanf("%d", &s[i]) ;
memset(sg, -1, sizeof(sg)) ;
sg[0] = 0 ;
//mex(10000) ;//不能打表,存在打不到的点
scanf("%d", &m) ;
while(m--){
scanf("%d", &l) ;
sum = 0 ;
while(l--){
scanf("%d", &t) ;
sum ^= mex(t) ;
}
if(sum) printf("W") ;
else printf("L") ;
}
printf("\n") ;
}
return 0 ;}
#include<cstring>
int s[101], sg[10001], k ;
int mex(int n){
if(sg[n]!=-1) return sg[n] ;
bool vis[101] ;//n最多有100个后继
int i ;
memset(vis, false, sizeof(vis)) ;
for(i=0; i<k; i++){
if(s[i]>n) continue ;//不能break, s无序
sg[n-s[i]] = mex(n-s[i]) ;
vis[sg[n-s[i]]] = true ;
}
for(i=0; vis[i]; i++) ;
sg[n] = i ;
return sg[n] ;
}
int main(){
int m, l, i, j, t, sum ;
while(~scanf("%d", &k)&&k){
for(i=0; i<k; i++)
scanf("%d", &s[i]) ;
memset(sg, -1, sizeof(sg)) ;
sg[0] = 0 ;
//mex(10000) ;//不能打表,存在打不到的点
scanf("%d", &m) ;
while(m--){
scanf("%d", &l) ;
sum = 0 ;
while(l--){
scanf("%d", &t) ;
sum ^= mex(t) ;
}
if(sum) printf("W") ;
else printf("L") ;
}
printf("\n") ;
}
return 0 ;}