【CCPC2017杭州F】

原题:

【CCPC2017杭州F】_第1张图片

 

 题意:

你和克总打炉石,克总有3个白板,你有3种不超过8张法术

第1种花c费对全体随从打x,并在本回合获得y点法强

第2种花c费打脸x点,并在本回合获得y点法强

第3种花c费对一个随从或者英雄打x

每回合你先行动,获得10点法力水晶,法强清0,然后克总行动,所有活着的随从踢脸,回合的最后克总会把所有3个随从复活回满血

告诉你一开始你和克总的血,克总3个白板的属性,以及你的手牌,问你能不能在3个回合内把克总打死

 

其实就是个搜索,把题意模拟出来就行了,不过搜索题实在太少见了,因此专门写了个博客。。。

裸搜会T,需要加个小剪枝,当你剩下的手牌在极限情况下都打不死克总时直接cut

太久没写搜索了居然连可行性剪枝都忘了,T了好几发。。。

不过这题其实还是不错的,模拟的难度适中,考验代码能力又不过于毒瘤

 

代码:

  1 #include
  2 #include
  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 }
View Code

 

你可能感兴趣的:(【CCPC2017杭州F】)