斗地主(codevs 4610)
牛牛最近迷上了一种叫斗地主的扑克游戏。 斗地主是一种使用黑桃、红心、梅花、
方片的 A 到 K 加上大小王的共 54 张牌来进行的扑克牌游戏。在斗地主中, 牌的大小关
系根据牌的数码表示如下: 3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王, 而花色并不
对牌的大小产生影响。 每一局游戏中,一副手牌由 n 张牌组成。游戏者每次可以根据规
定的牌型进行出牌, 首先打光自己的手牌一方取得游戏的胜利。
现在,牛牛只想知道,对于自己的若干组手牌, 分别最少需要多少次出牌可以将它
们打光。 请你帮他解决这个问题。
需要注意的是, 本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。
具体规则如下:
输入文件名为 landlords.in。
第一行包含用空格隔开的 2 个正整数T,n,表示手牌的组数以及每组手牌的张数。
接下来T组数据,每组数据n行, 每行一个非负整数ai,bi,对表示一张牌, 其中ai表
示牌的数码,bi表示牌的花色,中间用空格隔开。 特别的, 我们用1 来表示数码 A, 11 表
示数码 J, 12 表示数码 Q, 13 表示数码 K;黑桃、红心、梅花、方片分别用 1-4 来表示; 小
王的表示方法为 0 1, 大王的表示方法为 0 2。
输出文件名为 landlords.out。
共 T 行,每行一个整数,表示打光第i组手牌的最少次数。
输入样例1
1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
—————
输入样例2
1 17
12 3
4 3
2 3
5 4
10 2
3 3
12 2
0 1
1 3
10 1
6 2
12 1
11 3
5 2
12 4
2 2
7 2
输出样例1
3
—————
输出样例2
6
测试点, 我们约定手牌组数 与张数 的规模如下:
测试点编号 T n
1 100 2 |11 100 14
2 100 2 |12 100 15
3 100 3 |13 10 16
4 100 3 |14 10 17
5 100 4 |15 10 18
6 100 4 |16 10 19
7 100 10 |17 10 20
8 100 11 |18 10 21
9 100 12 |19 10 22
#include<cstdio>
#include<cstring>
#include<iostream>
#define M 18
using namespace std;
int n,x[M],cnt[],ans;
int read()
{
char c=getchar();int num=;
while(c<''||c>''){c=getchar();}
while(c>=''&&c<=''){num=num*+c-'';c=getchar();}
return num;
}
int calc()//先把能带着出的都出上
{
memset(cnt,,sizeof(cnt));
int res=;
for(int i=;i<M;i++)cnt[x[i]]++; //cnt[i]表示出现i次的数有几个
while(cnt[]&&cnt[]>=) res++,cnt[]--,cnt[]-=; //四带两对
while(cnt[]&&cnt[]>=) res++,cnt[]--,cnt[]-=; //四带二
while(cnt[]&&cnt[]>=) res++,cnt[]--,cnt[]-=; //三带一对
while(cnt[]&&cnt[]>=) res++,cnt[]--,cnt[]-=; //三带一
return res+cnt[]+cnt[]+cnt[]+cnt[]; //统计出当前答案
}
inline void dfs(int step)
{
if(step>ans) return;
//每更新一个状态之前,判断当前状态先出“n带m”是否更优
ans=min(ans,step+calc());
//三顺子
for(int i=;i<=M;i++)//最小从3开始
{
int j;
for(j=i;x[j]>=;j++);//可以确保 i~j-1 之间所有数字的数量都>=3
if(j-i>=)//至少连续2个
{
for(int t=j;t-i>=;t--)//从j枚举结束位置
{
for(int k=i;k<t;k++) x[k]-=;
dfs(step+);
for(int k=i;k<t;k++) x[k]+=;//回溯
}
}
}
//双顺子
for(int i=;i<=M;i++)
{
int j;
for(j=i;x[j]>=;j++);
if(j-i>=)
{
for(int t=j;t-i>=;t--)
{
for(int k=i;k<t;k++) x[k]-=;
dfs(step+);
for(int k=i;k<t;k++) x[k]+=;
}
}
}
//单顺子
for(int i=;i<=M;i++)
{
int j;
for(j=i;x[j]>=;j++);
if(j-i>=)
{
for(int t=j;t-i>=;t--)
{
for(int k=i;k<t;k++) x[k]-=;
dfs(step+);
for(int k=i;k<t;k++) x[k]+=;
}
}
}
}
int main()
{
int T=read(),n=read();
while(T--)
{
memset(x,,sizeof(x));
for(int i=;i<=n;i++)
{
int w=read(),c=read();
if(w==) w=;//把A转成13,其余数字减1
else if(w) w--;
x[w]++; //统计每个数字的个数
}
ans=calc();
dfs();
printf("%d\n", ans);
}
return ;
}
斗地主(codevs 4610)的更多相关文章
- 洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]
P2668 斗地主 326通过 2.6K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举NOIp提高组2015 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 出现未知错误是说梗啊 ...
- codevs 3289 花匠
题目:codevs 3289 花匠 链接:http://codevs.cn/problem/3289/ 这道题有点像最长上升序列,但这里不是上升,是最长"波浪"子序列.用动态规划可 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1285 二叉查找树STL基本用法
C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- codevs 1080 线段树点修改
先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- codevs 1082 线段树区间求和
codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...
- codevs 1052 地鼠游戏
1052 地鼠游戏 http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不 ...
随机推荐
- jQuery选择器之基本筛选选择器
<h2>基本筛选器</h2> <h3>:first/:last/:even/:odd</h3> <div class="left&quo ...
- 获取登陆信息 在created()方法中
// 获取登录信息 public async InitUser() { await sj.globalVar.Init(true); this.params.unitId = sj.globalVar ...
- CPLD
复杂可编程逻辑器件(Complex Programmable Logic Device, CPLD),CPLD适合用来实现各种运算和组合逻辑(combinational logic).一颗CPLD内等 ...
- Linux服务器用iotop命令分析服务器磁盘IO情况
Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦.如果会systemtap, 或者blktrace这些事情 ...
- Angularjs 实现 $(document).ready()的两种方法
1.在controller里面利用$on或者$watch bookControllers.controller('bookctrl_test', ['$scope', '$routeParams', ...
- pocket API学习笔记
最近安装了pocket离线阅读软件. 为了收藏需要的URL,每次都要打开浏览器.然后按google工具条上的pocket+. 网页多的时候,这个过程就非常缓慢. 根据pocket网站的API介绍,我可 ...
- 如何使用SAP CRM Marketing Survey创建一个市场问卷调查
使用事务码CRM_SURVEY_SUITE进行编辑.选中Activities这个应用类型,点击新建按钮: 双击Survey的根节点,点击编辑按钮维护Suvey的标题: Survey的正文布局类型(La ...
- centos6上安装mysql8.0版本
本博客是采用yum源的方式安装,非常的方便和快捷.(redhat 与centos7 等操作系统都可以采用此方法,步骤大体一致) mysql官网地址: https://dev.mysql.com 开 ...
- Python 循环结构语句
1.for循环:计次循环 2.while循环:条件循环 3.嵌套循环 4.跳转语句 一.for循环的使用 1.进行数值循环 利用数值循环输出三次‘你好’: >>> for i in ...
- OpenCV:应用篇
手势跟踪识别 车牌检测 人脸识别 去雾 图像阈值分割提取