首页 > 代码库 > HDU 4930 Fighting the Landlords(模拟)
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); //判断双方是否存在4267 ///////直接赢返回1,直接输返回-1,还有希望返回0 268 if(tt1 == 1 || tt1 == -1) //可以判断出结果 269 {270 printf(tt1 == 1? "Yes\n":"No\n");271 continue;272 }273 /////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0274 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\n":"No\n");282 }283 return 0;284 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。