• HDU 4930 Fighting the Landlords(模拟)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930

    解题报告:斗地主,加了一个四张可以带两张不一样的牌,也可以带一对,判断打出一手牌之后,如果对手没有能够大过你的牌就输出Yes,或者如果你把手上的牌一次性打完也输出Yes,否则输出No,代码有280多行,表示光是敲代码就花了一个多小时,手速还是太慢。

    1、首先判断手上的牌能不能一次打完

    如果一次性打不完:

    2、首先判断对方有没有一对王,有就输出No

    3、判断对手有没有四张的牌,如果有,再判断自己有没有四张的牌,如果对手有自己没有就是输,如果自己有对手没有自己有就是赢,如果两个人都有就看谁的更大,如果两个人都没有,则继续判断

    4、最后一步,尝试将自己的牌组合成前面的六种打法打出去,然后判断对手有没有可以大过自己的牌,如果有就继续判断,如果没有就是赢。

    详细情况看代码吧,有详细的注释。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<deque>
      6 using namespace std;
      7 
      8 void exchto(char* str,int* num)   //先把输入预处理成各种牌的张数num[i]表示第i大的牌有多少张 
      9 {
     10     int len = strlen(str);
     11     for(int i = 0;i < len;++i)
     12     {
     13         if(str[i] >= '3' && str[i] <= '9')
     14         num[str[i]-'0'-2]++; 
     15         if(str[i] == 'T') num[8]++;
     16         if(str[i] == 'J') num[9]++;
     17         if(str[i] == 'Q') num[10]++;
     18         if(str[i] == 'K') num[11]++;
     19         if(str[i] == 'A') num[12]++;
     20         if(str[i] == '2') num[13]++;
     21         if(str[i] == 'X') num[14]++;
     22         if(str[i] == 'Y') num[15]++;
     23     }
     24 }
     25 int judge_once(const int* num)    //判断能否一次打完或者自己有Nuke的情况 
     26 {
     27     if(num[14] && num[15])    //Nuke
     28     return 1;
     29     int n = 0;
     30     for(int i = 1;i <= 15;++i)
     31     if(num[i] != 0) n++;
     32     if(n > 3) return 0;   //牌种类数大于3不可能一次打完 
     33     if(n == 1) return 1;  //等于1一定可以一次打完
     34     if(n == 2)
     35     {
     36         for(int i = 1;i <= 13;++i)
     37         for(int j = 1;j < i;++j)
     38         {
     39             if(num[i] == 3 && num[j] >= 1 && num[j] <= 2)
     40             return 1;
     41             if(num[j] == 3 && num[i] >= 1 && num[i] <= 2)
     42             return 1;
     43             if(num[i] == 4 &&  num[j] == 2)
     44             return 1;
     45             if(num[j] == 4 && num[i] == 2)
     46             return 1;
     47         }
     48     }
     49     else if(n == 3)
     50     {
     51         int flag = -1;
     52         for(int i = 1;i <= 13;++i)
     53         if(num[i] == 4 && flag == -1) flag = 1;
     54         else if(num[i] == 4 && flag == 1) flag = 0;
     55         if(flag <= 0) return 0;   //没有4或者有多个4张的,不行 
     56         int m = 0;
     57         for(int i = 1;i <= 13;++i)
     58         if(num[i] == 1) m++;
     59         if(m == 2) return 1;
     60         return 0;
     61     }
     62     return 0;
     63 }
     64 int judge_have4(const int* num1,const int* num2)    //判断双方是否存在4 
     65 {
     66     int a = 16,b = 16;
     67     for(int i = 13;i >= 1;--i)
     68     if(num1[i] == 4)
     69     {
     70         a = i;
     71         break;
     72     }
     73     for(int i = 13;i >= 1;--i)
     74     if(num2[i] == 4)
     75     {
     76         b = i;
     77         break;
     78     }
     79     if(b != 16 && a == 16) return -1;  //对手有4而自己没有4张的情况
     80     if(a != 16 && b == 16) return 1;  //自己有4而对手没四
     81     if(a == 16 && b == 16) return 0;
     82     if(a >= b) return 1;
     83     else if(a < b) return -1;
     84 }
     85 /////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
     86 int  judge1(const int* num1,const int* num2)
     87 {
     88     int a = 16,b = 16;
     89     for(int i = 15;i >= 1;--i)
     90     if(num1[i] != 0)
     91     {
     92         a = i;
     93         break;
     94     }
     95     for(int i = 15;i >= 1;--i)
     96     if(num2[i] != 0)
     97     {
     98         b = i;
     99         break;
    100     }
    101     return a >= b;   //因为双方至少有一张牌,否则要判断是否有没找到的情况 
    102 }
    103 int judge2(const int* num1,const int* num2)
    104 {
    105     int a = 16,b = 16;
    106     for(int i = 15;i >= 1;--i)
    107     if(num1[i] >= 2)
    108     {
    109         a = i;
    110         break;
    111     }
    112     for(int i = 15;i >= 1;--i)
    113     if(num2[i] >= 2)
    114     {
    115         b = i;
    116         break;
    117     }
    118     if(a != 16 && b == 16) return 1;
    119     if(a == 16 && b == 16) return 0;
    120     if(a != 16 && b != 16) return a >= b;
    121     return 0;
    122 }
    123 int judge3(const int* num1,const int* num2)
    124 {
    125      int a = 16,b = 16;
    126      for(int i = 15;i >= 1;--i)
    127      if(num1[i] >= 3)
    128      {
    129          a = i;
    130          break;
    131      }
    132      for(int i = 15;i >= 1;--i)
    133      if(num2[i] >= 3)
    134      {
    135          b = i;
    136          break;
    137      }
    138      if(a != 16 && b == 16) return 1;
    139      if(a == 16 && b == 16) return 0;
    140      if(a != 16 && b != 16) return a >= b;
    141      return 0;
    142 }
    143 int judge4(const int* num1,const int* num2)
    144 {
    145     int a = 16,b = 16,c = 0,d = 0;
    146     for(int i = 15;i >= 1;--i)
    147     if(num1[i] >= 3)
    148     {
    149         a = i;
    150         break;
    151     }
    152     for(int i = 15;i >= 1;--i)
    153     if(num2[i] >= 3)
    154     {
    155         b = i;
    156         break;
    157     }
    158     if(a != 16)
    159     for(int i = 1;i <= 15;++i)
    160     if(i != a && num1[i] != 0)
    161     {
    162         c = 1;
    163         break;
    164     }
    165     if(b != 16)
    166     for(int i = 1;i <= 15;++i)
    167     if(i != b && num2[i] != 0)
    168     {
    169         d = 1;
    170         break;
    171     }
    172     if(a != 16 && c == 1 && (b == 16 || d == 0)) return 1;  //当对手有三个但没有1个另外的也不满足这种打法 
    173     if(a == 16 && b == 16) return 0;
    174     if(a != 16 && b != 16 && c == 1 && d == 1) return a >= b;
    175     return 0;
    176 }
    177 int judge5(const int* num1,const int* num2)
    178 {
    179     int a = 16,b = 16,c = 0,d = 0;
    180     for(int i = 15;i >= 1;--i)
    181     if(num1[i] >= 3)
    182     {
    183         a = i;
    184         break;
    185     }
    186     for(int i = 15;i >= 1;--i)
    187     if(num2[i] >= 3)
    188     {
    189         b = i;
    190         break;
    191     }
    192     if(a != 16)
    193     for(int i = 1;i <= 15;++i)
    194     if(i != a && num1[i] >= 2)
    195     {
    196         c = 1;
    197         break;
    198     }
    199     if(b != 16)
    200     for(int i = 1;i <= 15;++i)
    201     if(i != b && num2[i] >= 2)
    202     {
    203         d = 1;
    204         break;
    205     }
    206     if(a != 16 && c == 1 && (b == 16 || d == 0)) return 1;  //当对手有三个但没有1个另外的也不满足这种打法 
    207     if(a == 16 && b == 16) return 0;
    208     if(a != 16 && b != 16 && c == 1 && d == 1) return a >= b;
    209     return 0;
    210 }
    211 int judge6(const int* num1,const int* num2)
    212 {
    213     int a = 16,b = 16,c = 0,d = 0;
    214     for(int i = 15;i >= 1;--i)
    215     if(num1[i] >= 4)
    216     {
    217         a = i;
    218         break;
    219     }
    220     for(int i  = 15;i >= 1;--i)
    221     if(num2[i] >= 4)
    222     {
    223         b = i;
    224         break;
    225     }
    226     if(a != 16)
    227     for(int i = 1;i <= 15;++i)
    228     if(i != a && num1[i] >= 1)
    229     c++;
    230     if(b != 16)
    231     for(int i = 1;i <= 15;++i)
    232     if(i != b && num2[i] >= 1)
    233     d++;
    234     if(a != 16 && c >= 2 && b == 16) return 1;
    235     if(a == 16 && b == 16) return 0;
    236     if(a != 16 && b != 16 && c >= 2 && d >= 2) return a >= b;
    237     return 0;
    238 }
    239 
    240 int main()
    241 {
    242 //    freopen("1003.txt","r",stdin);
    243 //    freopen("out1.txt","w",stdout);
    244     int T;
    245     
    246     char one[20],two[20]; 
    247     int num1[20],num2[20];
    248     scanf("%d",&T);
    249     while(T--)
    250     {
    251         scanf("%s%s",one,two);
    252         memset(num1,0,sizeof(num1));
    253         memset(num2,0,sizeof(num2));
    254         exchto(one,num1);
    255         exchto(two,num2);
    256         if(judge_once(num1))    //判断能否一次打完 
    257         {
    258             puts("Yes");
    259             continue;
    260         }
    261         if(num2[14] && num2[15]) //对手有Nuke直接输 
    262         {
    263             puts("No");
    264             continue;
    265         }
    266         int tt1 = judge_have4(num1,num2);  //判断双方是否存在4
    267         ///////直接赢返回1,直接输返回-1,还有希望返回0 
    268         if(tt1 == 1 || tt1 == -1)    //可以判断出结果 
    269         {
    270             printf(tt1 == 1? "Yes
    ":"No
    ");
    271             continue;
    272         }
    273         /////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
    274         int flag = 0;
    275         flag = max(flag,judge1(num1,num2));
    276         flag = max(flag,judge2(num1,num2));
    277         flag = max(flag,judge3(num1,num2));
    278         flag = max(flag,judge4(num1,num2));
    279         flag = max(flag,judge5(num1,num2));
    280         flag = max(flag,judge6(num1,num2));
    281         printf(flag? "Yes
    ":"No
    ");
    282     }
    283     return 0;
    284 }        
    View Code
  • 相关阅读:
    限制转交订单-采购直接批准PO
    限制更改采购订单的供应商地点
    限制采购订单行数量的小数位
    加工费采购订单批准后禁止更改订单数量
    限制ITEM读取其它物料的物料描述
    采购订单限制订单“行号”过大的控制
    限制行表新增记录
    采购订单行需求时间必输
    报价单内,同一物料只允许一条行价格记录
    限制头表新增记录
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3901804.html
Copyright © 2020-2023  润新知