ACM-ICPC 2018 徐州賽區網路預賽 B. BE, GE or NE(博弈,記憶化搜尋)
阿新 • • 發佈:2018-12-24
樣例輸入1
3 -8 5 -5
3 1 1
2 0 1
0 2 1
樣例輸出1
Good Ending
樣例輸入2
3 0 10 3
0 0 1
0 10 1
0 2 1
樣例輸出2
Bad Ending
題意:A,B玩遊戲,n輪,A先手,給一個數字m,每一輪操作有a,b,c三個選擇,a為0則表示沒有a這個選擇,b,c同理,不可能三個選擇都不能選,可以選擇+a,-b或*(-1),A希望最後結果大於等於k,B希望最後結果小於等於l,兩人都選擇最有情況,l<k,若不能使得數字落在自己想要的區間,寧可使得數字落在區間l,k之間
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<set> using namespace std; int n,m,k,l; int a[1100],b[1100],c[1100]; int sum(int x){ if(x>100)return 100; if(x<-100)return -100; return x; } int main(){ scanf("%d%d%d%d",&n,&m,&k,&l); for(int i=1;i<=n;i++){ scanf("%d%d%d",&a[i],&b[i],&c[i]); } set<int>pre,now; for(int i=n;i>=1;i--){ if(i%2==1){//A選擇 for(int num=-100;num<=100;num++){ if(a[i]!=0){ if(pre.size()==0&&sum(num+a[i])>=k){ now.insert(num); continue; } if(pre.count(sum(num+a[i]))!=0){ now.insert(num); continue; } } if(b[i]!=0){ if(pre.size()==0&&sum(num-b[i])>=k){ now.insert(num); continue; } if(pre.count(sum(num-b[i]))!=0){ now.insert(num); continue; } } if(c[i]!=0){ if(pre.size()==0&&sum(-num)>=k){ now.insert(num); continue; } if(pre.count(sum(-num))!=0){ now.insert(num); continue; } } } } else{//B選擇 for(int num=-100;num<=100;num++){ if(a[i]!=0){ if(pre.size()==0){ if(sum(num+a[i])<k)continue; } else{ if(pre.count(sum(num+a[i]))==0)continue; } } if(b[i]!=0){ if(pre.size()==0){ if(sum(num-b[i])<k)continue; } else{ if(pre.count(sum(num-b[i]))==0)continue; } } if(c[i]!=0){ if(pre.size()==0){ if(sum(-num)<k)continue; } else{ if(pre.count(sum(-num))==0)continue; } } now.insert(num); } } pre.clear(); pre=now; if(now.size()==0)break; now.clear(); } if(pre.count(m)!=0){ printf("Good Ending\n"); return 0; } pre.clear(); now.clear(); for(int i=n;i>=1;i--){ if(i%2==0){//B選擇 for(int num=-100;num<=100;num++){ if(a[i]!=0){ if(pre.size()==0&&sum(num+a[i])<=l){ now.insert(num); continue; } if(pre.count(sum(num+a[i]))!=0){ now.insert(num); continue; } } if(b[i]!=0){ if(pre.size()==0&&sum(num-b[i])<=l){ now.insert(num); continue; } if(pre.count(sum(num-b[i]))!=0){ now.insert(num); continue; } } if(c[i]!=0){ if(pre.size()==0&&sum(-num)<=l){ now.insert(num); continue; } if(pre.count(sum(-num))!=0){ now.insert(num); continue; } } } } else{//A選擇 for(int num=-100;num<=100;num++){ if(a[i]!=0){ if(pre.size()==0){ if(sum(num+a[i])>l)continue; } else{ if(pre.count(sum(num+a[i]))==0)continue; } } if(b[i]!=0){ if(pre.size()==0){ if(sum(num-b[i])>l)continue; } else{ if(pre.count(sum(num-b[i]))==0)continue; } } if(c[i]!=0){ if(pre.size()==0){ if(sum(-num)>l)continue; } else{ if(pre.count(sum(-num))==0)continue; } } now.insert(num); } } pre.clear(); pre=now; if(now.size()==0)break; now.clear(); } if(pre.count(m)!=0){ printf("Bad Ending\n"); return 0; } printf("Normal Ending\n"); return 0; }