uva1482:Playing With Stones (SG函式)
阿新 • • 發佈:2018-12-15
題意:有N堆石子,每次可以取一堆的不超過半數的石子,沒有可取的為輸。
思路:假設只有一堆,手推出來,數量x可以表示為2^p-1形式的必輸。 但是沒什麼用,因為最後要的不是0和1,而是SG函式;所以必輸的為0,那麼其他的呢?
我們可以發現SG=0的位置是1,3,7,15,31....
SG=1, 2,5,11,23....
可以推出來,也可以打表。
(水題,這題可以放這裡以後講課用。
sg[1]=0; for(int i=2;i<=30;i++){ memset(vis,0,sizeof(vis)); for(int j=1;j<=i/2;j++) vis[sg[i-j]]=1; for(int j=0;;j++){ if(!vis[j]) {sg[i]=j; break;} } } for(int i=1;i<=30;i++) cout<<i<<""<<sg[i]<<endl;
完整程式碼:
#include<bits/stdc++.h> #define ll long long using namespace std; ll SG(ll x){ if(x&1LL) return SG(x/2); return x/2; } int main() { int T,N,ans; ll x,q; scanf("%d",&T); while(T--){ ans=0; scanf("%d",&N);for(int i=1;i<=N;i++){ scanf("%lld",&x); ans^=SG(x); } if(ans) puts("YES"); else puts("NO"); } return 0; }