1. 程式人生 > >洛谷 P2148 [SDOI2009]E&D

洛谷 P2148 [SDOI2009]E&D

family n) cnblogs std 測試 size 編號 getchar 個數

題目描述

小E 與小W 進行一項名為“E&D”遊戲。

遊戲的規則如下: 桌子上有2n 堆石子,編號為1..2n。其中,為了方便起見,我們將第2k-1 堆與第2k 堆 (1 ≤ k ≤ n)視為同一組。第i堆的石子個數用一個正整數Si表示。 一次分割操作指的是,從桌子上任取一堆石子,將其移走。然後分割它同一組的另一堆 石子,從中取出若幹個石子放在被移走的位置,組成新的一堆。操作完成後,所有堆的石子 數必須保證大於0。顯然,被分割的一堆的石子數至少要為2。 兩個人輪流進行分割操作。如果輪到某人進行操作時,所有堆的石子數均為1,則此時 沒有石子可以操作,判此人輸掉比賽。

小E 進行第一次分割。他想知道,是否存在某種策 略使得他一定能戰勝小W。因此,他求助於小F,也就是你,請你告訴他是否存在必勝策略。 例如,假設初始時桌子上有4 堆石子,數量分別為1,2,3,1。小E可以選擇移走第1堆, 然後將第2堆分割(只能分出1 個石子)。接下來,小W 只能選擇移走第4 堆,然後將第3 堆分割為1 和2。最後輪到小E,他只能移走後兩堆中數量為1 的一堆,將另一堆分割為1 和1。這樣,輪到小W 時,所有堆的數量均為1,則他輸掉了比賽。故小E 存在必勝策略。

輸入輸出格式

輸入格式:

第一行是一個正整數T(T ≤ 20),表示測試數據數量。接下來有T組 數據。 對於每組數據,第一行是一個正整數N,表示桌子上共有N堆石子。其中,輸入數據保 證N是偶數。 第二行有N個正整數S1..SN,分別表示每一堆的石子數。

輸出格式:

包含T 行。對於每組數據,如果小E 必勝,則輸出一行”YES”,否則 輸出”NO”。

輸入輸出樣例

輸入樣例#1:
2
4
1 2 3 1
6
1 1 1 1 1 1
輸出樣例#1:
YES
NO
【數據規模和約定】
對於20%的數據,N = 2;
對於另外20%的數據,N ≤ 4,Si ≤ 50;
對於100%的數據,N ≤ 2×104,Si ≤ 2×109。

一眼SG函數+打表找規律
但這個規律真是日了狗了
這道題充分說明了圖形界面的優越性,我打了一堆a=1 b=1 sg=0這種東西出來,一點用都沒有
打個矩陣出來一看就知道了
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13
#include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d\n",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 100010; 31 const int MAXNODE = 100010; 32 const int MAXEDGE = 2*MAXNODE; 33 char BUF,*buf; 34 int read(){ 35 char c=getchar();int f=1,x=0; 36 while(!isdigit(c)){if(c==-) f=-1;c=getchar();} 37 while(isdigit(c)){x=x*10+c-0;c=getchar();} 38 return f*x; 39 } 40 char get_ch(){ 41 char c=getchar(); 42 while(!isalpha(c)) c=getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 int n; 47 int getsg(int a,int b){ 48 ull tmp=2; 49 for(int i=0;;i++,tmp*=2){ 50 if((a-1)%(tmp)<tmp/2&&(b-1)%(tmp)<tmp/2) return i; 51 } 52 } 53 void get_input(); 54 void work(); 55 int main() { 56 int T=read(); 57 58 while(T--){ 59 get_input(); 60 work(); 61 } 62 return 0; 63 } 64 void work(){ 65 66 } 67 void get_input(){ 68 n=read(); 69 int ans=0; 70 rep0(i,n/2){ 71 int a=read(),b=read(); 72 ans^=getsg(a,b); 73 } 74 if(ans) printf("YES\n"); else printf("NO\n"); 75 }

 

洛谷 P2148 [SDOI2009]E&D