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

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

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

如果一次性打不完:

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

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

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

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

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<deque>
using namespace std; void exchto(char* str,int* num) //先把输入预处理成各种牌的张数num[i]表示第i大的牌有多少张
{
int len = strlen(str);
for(int i = ;i < len;++i)
{
if(str[i] >= '' && str[i] <= '')
num[str[i]-''-]++;
if(str[i] == 'T') num[]++;
if(str[i] == 'J') num[]++;
if(str[i] == 'Q') num[]++;
if(str[i] == 'K') num[]++;
if(str[i] == 'A') num[]++;
if(str[i] == '') num[]++;
if(str[i] == 'X') num[]++;
if(str[i] == 'Y') num[]++;
}
}
int judge_once(const int* num) //判断能否一次打完或者自己有Nuke的情况
{
if(num[] && num[]) //Nuke
return ;
int n = ;
for(int i = ;i <= ;++i)
if(num[i] != ) n++;
if(n > ) return ; //牌种类数大于3不可能一次打完
if(n == ) return ; //等于1一定可以一次打完
if(n == )
{
for(int i = ;i <= ;++i)
for(int j = ;j < i;++j)
{
if(num[i] == && num[j] >= && num[j] <= )
return ;
if(num[j] == && num[i] >= && num[i] <= )
return ;
if(num[i] == && num[j] == )
return ;
if(num[j] == && num[i] == )
return ;
}
}
else if(n == )
{
int flag = -;
for(int i = ;i <= ;++i)
if(num[i] == && flag == -) flag = ;
else if(num[i] == && flag == ) flag = ;
if(flag <= ) return ; //没有4或者有多个4张的,不行
int m = ;
for(int i = ;i <= ;++i)
if(num[i] == ) m++;
if(m == ) return ;
return ;
}
return ;
}
int judge_have4(const int* num1,const int* num2) //判断双方是否存在4
{
int a = ,b = ;
for(int i = ;i >= ;--i)
if(num1[i] == )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] == )
{
b = i;
break;
}
if(b != && a == ) return -; //对手有4而自己没有4张的情况
if(a != && b == ) return ; //自己有4而对手没四
if(a == && b == ) return ;
if(a >= b) return ;
else if(a < b) return -;
}
/////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
int judge1(const int* num1,const int* num2)
{
int a = ,b = ;
for(int i = ;i >= ;--i)
if(num1[i] != )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] != )
{
b = i;
break;
}
return a >= b; //因为双方至少有一张牌,否则要判断是否有没找到的情况
}
int judge2(const int* num1,const int* num2)
{
int a = ,b = ;
for(int i = ;i >= ;--i)
if(num1[i] >= )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] >= )
{
b = i;
break;
}
if(a != && b == ) return ;
if(a == && b == ) return ;
if(a != && b != ) return a >= b;
return ;
}
int judge3(const int* num1,const int* num2)
{
int a = ,b = ;
for(int i = ;i >= ;--i)
if(num1[i] >= )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] >= )
{
b = i;
break;
}
if(a != && b == ) return ;
if(a == && b == ) return ;
if(a != && b != ) return a >= b;
return ;
}
int judge4(const int* num1,const int* num2)
{
int a = ,b = ,c = ,d = ;
for(int i = ;i >= ;--i)
if(num1[i] >= )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] >= )
{
b = i;
break;
}
if(a != )
for(int i = ;i <= ;++i)
if(i != a && num1[i] != )
{
c = ;
break;
}
if(b != )
for(int i = ;i <= ;++i)
if(i != b && num2[i] != )
{
d = ;
break;
}
if(a != && c == && (b == || d == )) return ; //当对手有三个但没有1个另外的也不满足这种打法
if(a == && b == ) return ;
if(a != && b != && c == && d == ) return a >= b;
return ;
}
int judge5(const int* num1,const int* num2)
{
int a = ,b = ,c = ,d = ;
for(int i = ;i >= ;--i)
if(num1[i] >= )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] >= )
{
b = i;
break;
}
if(a != )
for(int i = ;i <= ;++i)
if(i != a && num1[i] >= )
{
c = ;
break;
}
if(b != )
for(int i = ;i <= ;++i)
if(i != b && num2[i] >= )
{
d = ;
break;
}
if(a != && c == && (b == || d == )) return ; //当对手有三个但没有1个另外的也不满足这种打法
if(a == && b == ) return ;
if(a != && b != && c == && d == ) return a >= b;
return ;
}
int judge6(const int* num1,const int* num2)
{
int a = ,b = ,c = ,d = ;
for(int i = ;i >= ;--i)
if(num1[i] >= )
{
a = i;
break;
}
for(int i = ;i >= ;--i)
if(num2[i] >= )
{
b = i;
break;
}
if(a != )
for(int i = ;i <= ;++i)
if(i != a && num1[i] >= )
c++;
if(b != )
for(int i = ;i <= ;++i)
if(i != b && num2[i] >= )
d++;
if(a != && c >= && b == ) return ;
if(a == && b == ) return ;
if(a != && b != && c >= && d >= ) return a >= b;
return ;
} int main()
{
// freopen("1003.txt","r",stdin);
// freopen("out1.txt","w",stdout);
int T; char one[],two[];
int num1[],num2[];
scanf("%d",&T);
while(T--)
{
scanf("%s%s",one,two);
memset(num1,,sizeof(num1));
memset(num2,,sizeof(num2));
exchto(one,num1);
exchto(two,num2);
if(judge_once(num1)) //判断能否一次打完
{
puts("Yes");
continue;
}
if(num2[] && num2[]) //对手有Nuke直接输
{
puts("No");
continue;
}
int tt1 = judge_have4(num1,num2); //判断双方是否存在4
///////直接赢返回1,直接输返回-1,还有希望返回0
if(tt1 == || tt1 == -) //可以判断出结果
{
printf(tt1 == ? "Yes\n":"No\n");
continue;
}
/////////下面尝试前六种不同的打法,如果可以用该打法赢,返回1,否则返回0
int flag = ;
flag = max(flag,judge1(num1,num2));
flag = max(flag,judge2(num1,num2));
flag = max(flag,judge3(num1,num2));
flag = max(flag,judge4(num1,num2));
flag = max(flag,judge5(num1,num2));
flag = max(flag,judge6(num1,num2));
printf(flag? "Yes\n":"No\n");
}
return ;
}

HDU 4930 Fighting the Landlords(模拟)的更多相关文章

  1. HDU 4930 Fighting the Landlords(暴力枚举+模拟)

    HDU 4930 Fighting the Landlords 题目链接 题意:就是题中那几种牌型.假设先手能一步走完.或者一步让后手无法管上,就赢 思路:先枚举出两个人全部可能的牌型的最大值.然后再 ...

  2. HDU 4930 Fighting the Landlords(扯淡模拟题)

    Fighting the Landlords 大意: 斗地主... . 分别给出两把手牌,肯定都合法.每张牌大小顺序是Y (i.e. colored Joker) > X (i.e. Black ...

  3. HDU 4930 Fighting the Landlords --多Trick,较复杂模拟

    题意:两个人A和B在打牌,只有题目给出的几种牌能出若A第一次出牌B压不住或者A一次就把牌出完了,那么A赢,输出Yes,否则若A牌没出完而且被B压住了,那么A输,输出No. 解法:知道规则,看清题目,搞 ...

  4. 2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

    题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. #inc ...

  5. hdu 4930 Fighting the Landlords--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 Fighting the Landlords Time Limit: 2000/1000 MS ...

  6. HDU4930 Fighting the Landlords 模拟

    Fighting the Landlords Fighting the Landlords Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  7. hdu4930 Fighting the Landlords(模拟 多校6)

    题目链接:pid=4930">http://acm.hdu.edu.cn/showproblem.php? pid=4930 Fighting the Landlords Time L ...

  8. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  9. hdu 4930 斗地主恶心模拟

    http://acm.hdu.edu.cn/showproblem.php?pid=4930 就是两个人玩斗地主,有8种牌型,单张,一对,三张,三带一,三带对,四带二,四炸,王炸.问先手能否一次出完牌 ...

随机推荐

  1. web中异步和同步的理解

    普通的B/S模式就是同步,而AJAX技术就是异步,当然XMLHttpReques有同步的选项. 同步:提交请求->等待服务器处理->处理完毕返回.这个期间客户端浏览器不能干任何事. 异步: ...

  2. Spring-data-jpa 的@modifying注解

    在项目的进行中需要通过 @Modifying 注解完成修改操作(注意:不支持新增) 1.之前有一个业务需要先查询一个结果集,然后将满足结果集中某个条件的另外一张表中的字段做一个属性值的更改,这个更改可 ...

  3. Java数据结构——有序链表

    //================================================= // File Name : SortedList_demo //--------------- ...

  4. svn 强制用户添加注释 和 允许用户修改注释

    当我们用TortoiseSVN提交代码时,有很多人不喜欢写注释,导致以后代码版本多,也不清楚哪个版本到底改了什么东西.所以在提交的时候,我会强制要求添加注释.这是如何实现的?这个话题就涉及到了svn的 ...

  5. 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层

    系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在数据访问层应用Repository模式来隔离对领域对象的细节操作是很有意义的.它位于映射层 ...

  6. (新手向)基于Bootstrap的简单轮播图的手机实现

    个人电脑里存了不少适合手机欣赏的图片,但是放手机里看是件很占据资源的事.鉴于家里有一台电脑经常开着,正好用来做家庭局域网共享,于是笔者就设想通过一种比较简单环保的思路.通过手机访问电脑内的图片. 首先 ...

  7. 字符串哈希函数(String Hash Functions)

    哈希函数举例 http://www.cse.yorku.ca/~oz/hash.html Node.js使用的哈希函数 https://www.npmjs.org/package/string-has ...

  8. Python socket编程

    一.什么是socket: socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求 ...

  9. python抓取网站URL小工具

    1.安装Python requests模块(通过pip): 环境搭建好了! 2.测试一下抓取URL的过程: 抓取出来的URL有JavaScript代码,正则上还有待更加完善,有兴趣的可以研究下~! 工 ...

  10. Yii2 打印sql语句和批量插入数据

    打印sql语句: $model->find()->createCommand()->getRawSql(); 批量插入 Yii::$app->db->createComm ...