【CCPC2017杭州F】
原题:
题意:
你和克总打炉石,克总有3个白板,你有3种不超过8张法术
第1种花c费对全体随从打x,并在本回合获得y点法强
第2种花c费打脸x点,并在本回合获得y点法强
第3种花c费对一个随从或者英雄打x
每回合你先行动,获得10点法力水晶,法强清0,然后克总行动,所有活着的随从踢脸,回合的最后克总会把所有3个随从复活回满血
告诉你一开始你和克总的血,克总3个白板的属性,以及你的手牌,问你能不能在3个回合内把克总打死
其实就是个搜索,把题意模拟出来就行了,不过搜索题实在太少见了,因此专门写了个博客。。。
裸搜会T,需要加个小剪枝,当你剩下的手牌在极限情况下都打不死克总时直接cut
太久没写搜索了居然连可行性剪枝都忘了,T了好几发。。。
不过这题其实还是不错的,模拟的难度适中,考验代码能力又不过于毒瘤
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 struct nds{int x,y,z,w,v;}a[4],b[9]; 5 int n,m,o; 6 int q[4][9][2],hd[4]; 7 void ist(int x,int y,int z){ 8 ++hd[x]; 9 q[x][hd[x]][0]=y; 10 q[x][hd[x]][1]=z; 11 } 12 void pp(int x){ 13 --hd[x]; 14 } 15 bool chck(int z){ 16 int bwl=0,cnt=z; 17 for(int i=1;i<=n;++i)if(b[i].w==0 && b[i].x!=3) 18 cnt+=b[i].z; 19 for(int i=1;i<=n;++i)if(b[i].w==0 && b[i].x!=1) 20 bwl+=cnt+b[i].y; 21 return bwl>=a[0].y; 22 } 23 void prvs(){ 24 for(int i=1;i<=3;++i) hd[i]=0; 25 } 26 bool dfs(int x,int y,int z,int mk){ 27 if(x==4) return false; 28 if(a[0].y<=0) return true; 29 if(m<=0) return false; 30 if(!chck(z)) return false; 31 /*int z[4],w[9]; 32 for(int i=0;i<=3;++i) z[i]=a[i].y; 33 for(int i=1;i<=n;++i) w[i]=b[i].w;*/ 34 for(int i=1;i<=n;++i)if(b[i].w==0 && y>=b[i].v){ 35 //if(b[i].x==1 && mk==0){ 36 if(b[i].x==1){ 37 ist(x,i,-1); 38 for(int j=1;j<=3;++j) a[j].y-=z+b[i].y; 39 b[i].w=1; 40 if(dfs(x,y-b[i].v,z+b[i].z,mk)) return true; 41 b[i].w=0; 42 for(int j=1;j<=3;++j) a[j].y+=z+b[i].y; 43 pp(x); 44 } 45 //else if(b[i].x==2 && mk==0){ 46 else if(b[i].x==2){ 47 ist(x,i,-1); 48 a[0].y-=z+b[i].y; 49 b[i].w=1; 50 if(dfs(x,y-b[i].v,z+b[i].z,mk)) return true; 51 b[i].w=0; 52 a[0].y+=z+b[i].y; 53 pp(x); 54 } 55 else{ 56 //for(int j=0;j<=3;++j)if(a[j].y>0){ 57 for(int j=0;j<=3;++j){ 58 ist(x,i,j); 59 a[j].y-=z+b[i].y; 60 b[i].w=1; 61 if(dfs(x,y-b[i].v,z,1)) return true; 62 b[i].w=0; 63 a[j].y+=z+b[i].y; 64 pp(x); 65 } 66 } 67 } 68 int w[4]; 69 for(int j=1;j<=3;++j){ 70 if(a[j].y>0) m-=a[j].x; 71 w[j]=a[j].y; 72 a[j].y=a[j].z; 73 } 74 if(dfs(x+1,10,0,0)) return true; 75 for(int j=1;j<=3;++j){ 76 a[j].y=w[j]; 77 if(a[j].y>0) m+=a[j].x; 78 } 79 /*for(int i=1;i<=n;++i) b[i].w=w[i]; 80 for(int i=0;i<=3;++i) a[i].y=z[i];*/ 81 return false; 82 } 83 int main(){ 84 int T; cin>>T; 85 while(T --> 0){ 86 prvs(); 87 scanf("%d",&n); 88 scanf("%d%d",&m,&o); 89 a[0].x=0,a[0].y=o,a[0].z=o; 90 for(int i=1;i<=3;++i) 91 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); 92 for(int i=1;i<=n;++i){ 93 //scanf("%d%d%d%d",&b[i].x,&b[i].v,&b[i].y,&b[i].z); 94 scanf("%d",&b[i].x); 95 if(b[i].x==3) scanf("%d%d",&b[i].v,&b[i].y); 96 else scanf("%d%d%d",&b[i].v,&b[i].y,&b[i].z); 97 b[i].w=0; 98 } 99 if(dfs(1,10,0,0)){ 100 printf("Yes\n"); 101 for(int i=1;i<=3;++i){ 102 printf("%d\n",hd[i]); 103 if(hd[i]!=0){ 104 for(int j=1;j<=hd[i];++j) 105 printf("%d ",q[i][j][0]); 106 printf("\n"); 107 for(int j=1;j<=hd[i];++j) 108 printf("%d ",q[i][j][1]); 109 printf("\n"); 110 } 111 } 112 } 113 else{ 114 printf("No\n"); 115 } 116 } 117 return 0; 118 }