zoj3459

先算出所有能得出24的组合,再直接暴搜。

/*
 * Author:  xioumu
 * Created Time:  2011-10-24 13:45:29
 * File Name: p3459.cpp
 */
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define esp 1e-8
using namespace std;
int num[4][10],col[4][10];
int g[11][11][11][11];
int n,m;
void init()
{
   int i,j,k,r,w;
   char c;
   memset(num,0,sizeof(num));
   memset(col,0,sizeof(col));
   for(i=1;i<=4;i++)
   {  scanf("%d ",&num[0][i]);
      scanf("%c",&c);
      if(c == 'r')  col[0][i] = 1;
      else col[0][i] = 2;
   }
   
   scanf("%d %d",&n,&m);
   for(i=1;i<=n;i++)
   {  scanf("%d ",&num[1][i]);
      scanf("%c",&c);
      if(c == 'r')  col[1][i] = 1;
      else col[1][i] = 2;      
   } 
   
   for(i=1;i<=m;i++)
   {  scanf("%d ",&num[2][i]);
      scanf("%c",&c);
      if(c == 'r')  col[2][i] = 1;
      else col[2][i] = 2;      
   }
   
   //printf("--\n");
}
int v[10]={0};
int get(double kk[],int ff[],int h)
{
   int i,j,oldf[10],f[10],w;
   double oldk[10],k[10];
   memcpy(k,kk,sizeof(k));
   memcpy(f,ff,sizeof(f));
   memcpy(oldk,k,sizeof(oldk));
   memcpy(oldf,f,sizeof(oldf));
   if(h == 1) 
   {  
      if(abs(k[1]-24) < esp) return 1;
      else return 0;
   }
   for(i=1;i<=h-1;i++)
   {  if(f[i] == 4 && abs(k[i+1]) < esp) continue; 
      if(f[i] == 1) k[i] += k[i+1];
      if(f[i] == 2) k[i] -= k[i+1];
      if(f[i] == 3) k[i] *= k[i+1];
      if(f[i] == 4) k[i] /= k[i+1];
      for(j=i;j<=3;j++)   f[j] = f[j+1];
      for(j=i+1;j<=4;j++) k[j] = k[j+1];
      w = get(k,f,h-1);
      memcpy(k,oldk,sizeof(oldk));
      memcpy(f,oldf,sizeof(oldf));
      if(w == 1) return 1;
   }
   //if(h == 4)
     //printf("%d %d %d\n",f[1],f[2],f[3]);
   return 0;
}
int pan(int a[])
{
   int i,j,r,w,f[10];
   double k[10];
   memset(f,0,sizeof(f));
   for(i=1;i<=4;i++)
      k[i] = a[i];
   
   for(f[1]=1; f[1]<=4; f[1]++)
      for(f[2]=1; f[2]<=4; f[2]++)
         for(f[3]=1; f[3]<=4; f[3]++)
         {  //printf("%d %d %d %d %d %d %d\n",k[1],f[1],k[2],f[2],k[3],f[3],k[4]);
            
            if(a[1] == 6 && a[2] == 1 && a[3] == 3 && a[4] == 4 
               && f[1] == 4 && f[2] == 2 && f[3] == 4)
               j = 1;
            
            if( get(k, f, 4) ) return 1;
            
         }
   return 0;
}
int ok(int a[])
{
   int b[10];
   memcpy(b,a,sizeof(b));
   sort(b+1,b+5);
   return g[ b[1] ][ b[2] ][ b[3] ][ b[4] ];
}
int fun(int nn,int mm,int h)
{
   int i,j,k,r,w,ans=-1;
   int oldnum[4][10],oldcol[4][10];
   memcpy(oldnum,num,sizeof(oldnum));
   memcpy(oldcol,col,sizeof(oldcol));
   //printf("%d %d\n",nn,mm);  
   if(h == 0)
   {  
      if( ok(num[0]) )
      {  // printf("<.>\n");
         if( (nn != n || mm != m) || fun(nn,mm,1)  ) return 1;
      }
      for(i=1;i<=n;i++)
         if(v[i] == 0)
            for(j=1;j<=4;j++)
            {  num[0][j] = num[1][i];
               col[0][j] = col[1][i];
               v[i] = 1;
               ans = fun(nn-1,mm,1);
               v[i] = 0;
               num[0][j] = oldnum[0][j];
               col[0][j] = oldcol[0][j];
               
               if(ans == 1) return 1;
            }
      return 0;
   } 
   if(h == 1)
   {  
    // printf("----"); 
      if( ok(num[0] ) == 0)
      {   return 0;
      }
      //printf("%d %d %d %d\n",num[0][1],num[0][2],num[0][3],num[0][4]);
      for(i=1;i<=m;i++)
         if(col[2][i] == 2) 
            for(j=1;j<=4;j++)
            { // printf("%d %d : %d %d\n",num[0][j], col[0][j], num[2][i], col[2][i]); 
               swap(num[0][j],num[2][i]);
               swap(col[0][j],col[2][i]);
               //printf("%d %d : %d %d\n",num[0][j], col[0][j], num[2][i], col[2][i]);
               ans = fun(nn,mm-1,0);
               swap(num[0][j],num[2][i]);
               swap(col[0][j],col[2][i]);
               
               if(ans == 0) return 0;
            }
      return 1;
   }
  
}
void solve()
{
   int i,j,k,r,w;
   memset(v,0,sizeof(v));
   if( fun(n,m,0) )  printf("Sima Yi Wins!\n");
   else printf("Zhang Jiao Wins!\n");
}
void prepare()
{
   int i=1,a[10],num[10];
   for(num[1]=1;num[1]<=10;num[1]++)
      for(num[2]=1;num[2]<=10;num[2]++)
         for(num[3]=1;num[3]<=10;num[3]++)
            for(num[4]=1;num[4]<=10;num[4]++)
            {  if( pan(num) == 1)
               {  memcpy(a,num,sizeof(a));
                  sort(a+1,a+5);
                  g[ a[1] ][ a[2] ][ a[3] ][ a[4] ] = 1;
               }
            }
}
int main()
{
   int i,t;
   freopen("p3459.in","r",stdin);
   memset(g,0,sizeof(g));
   prepare();
   scanf("%d",&t);
   for(i=1;i<=t;i++)
   { 
      init();
      solve();
      //printf("%d %d\n",i,t);
      //printf("-----"); 
   }
   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值