题目描述

牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。

现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。

需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。

具体规则如下:

输入输出格式

输入格式:

第一行包含用空格隔开的2个正整数Tn,表示手牌的组数以及每组手牌的张数。

接下来T组数据,每组数据n行,每行一个非负整数对aibi表示一张牌,其中ai示牌的数码,bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。

输出格式:

共T行,每行一个整数,表示打光第i手牌的最少次数。

输入输出样例

输入样例#1:

1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
输出样例#1:

3
输入样例#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
输出样例#2:

6

说明

样例1说明

共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。

对于不同的测试点, 我们约定手牌组数T与张数n的规模如下:

数据保证:所有的手牌都是随机生成的。

0.0:斗地主,感觉写完这个代码我都成了斗地主大神了。

思路:

  dfs+简易剪枝+简易a*(我也不知道算不算a*);

  dfs参数记录层数

  按消耗牌多少的贪心顺序搜索

  有几种情况可以不用搜索(但我还是搜索了)

  可以用a*估算出来

  最后剩下有单牌,对子,三张牌,4炸弹的时候可以直接算出来;

  还有一个剪枝,一个简简单单的剪枝(if(x>=ans) return;);

  这个因为省略了很多情况所以并不很慢;

  反正我是过了;

  来,上代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,jk,kl,ai,bi,hand[],ans=0x7fffffff;
int t,c[];
int A_star()
{
memset(c,,sizeof(c));
int tot=,kll=;
for(int i=;i<=;i++) c[hand[i]]++;//统计当前还剩的牌数
while(c[]&&c[]>) c[]--,c[]-=,tot++;//四带一对
while(c[]&&c[]>) c[]--,c[]-=,tot++;//四带两单
while(c[]&&c[]) c[]--,c[]--,tot++;//三带二
while(c[]&&c[]) c[]--,c[]--,tot++;//三带一
for(int i=;i<=;i++) kll+=c[i];
return tot+kll;//带牌+三张 对子 单张
}
void dfs(int x)
{
// num=min(num,ans);
// printf("%d %d ",x,ans);
// for(int i=1;i<=15;i++) printf("%d ",hand[i]);
// printf("\n");
if(x>=ans) return;
int pd=;
int cur=;
for(int i=;i<=;i++)//
{
if(hand[i]>=)
{
hand[i]-=;
for(int j=;j<=;j++)
{
if(j!=i&&hand[j]>=)
{
hand[j]-=;
for(int v=;v<=;v++)
{
if(hand[v]>=&&v!=j)
{
hand[v]-=;
// printf("1 ");
dfs(x+);
hand[v]+=;
}
}
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=;i<=;i++)//
{
if(hand[i]>=)
{
hand[i]-=;
for(int j=;j<=;j++)
{
if(j!=i&&hand[j]>=)
{
hand[j]-=;
for(int v=;v<=;v++)
{
if(hand[v]>=&&v!=i)
{
hand[v]-=;
/// printf("2 ");
dfs(x+);
hand[v]+=;
}
}
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=;i<=;i++)//3s
{
cur=;
if(hand[i]>=&&i<=){
for(int j=i;j<=;j++)
{
if(hand[j]>=) cur++;
else break;
}
for(int j=cur;j>=;j--)
{
for(int v=i;v<=j+i-;v++) hand[v]-=;
// printf("3 ");
dfs(x+);
for(int v=i;v<=j+i-;v++) hand[v]+=;
}
}
}
for(int i=;i<=;i++)//2s
{
cur=;
if(hand[i]>=&&i<=){
for(int j=i;j<=;j++)
{
if(hand[j]>=) cur++;
else break;
}
for(int j=cur;j>=;j--)
{
for(int v=i;v<=j+i-;v++) hand[v]-=;
// printf("4 ");
dfs(x+);
for(int v=i;v<=j+i-;v++) hand[v]+=;
}
}
}
for(int i=;i<=;i++)//1s
{
cur=;
if(hand[i]>=&&i<=){
for(int j=i;j<=;j++)
{
if(hand[j]>=) cur++;
else break;
}
for(int j=cur;j>=;j--)
{
for(int v=i;v<=j+i-;v++) hand[v]-=;
// printf("5 ");
dfs(x+);
for(int v=i;v<=j+i-;v++) hand[v]+=;
}
}
}
for(int i=;i<=;i++)
{
if(hand[i]>=)
{
hand[i]-=;
for(int j=;j<=;j++)
{
if(j!=i&&hand[j]>=)
{
hand[j]-=;
// printf("6 ");
dfs(x+);
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=;i<=;i++)
{
if(hand[i]>=)
{
hand[i]-=;
for(int j=;j<=;j++)
{
if(j!=i&&hand[j]>=)
{
hand[j]-=;
// printf("7 ");
dfs(x+);
hand[j]+=;
}
}
hand[i]+=;
}
}
if(hand[]>=&&hand[]>=)
{
hand[]--;
hand[]--;
// printf("8 ");
dfs(x+);
hand[]++;
hand[]++;
}
jk=A_star();
if(x+jk>=ans) return;
else ans=x+jk;
}
int main()
{
scanf("%d%d",&t,&n);
while(t--)
{
memset(hand,,sizeof(hand));
ans=0x7fffffff;
for(int i=;i<=n;i++)
{
cin>>ai>>bi;
if(ai!=)
{
if(ai>=) hand[ai-]++;
else hand[+ai]++;
}
else
{
if(bi==) hand[]++;
else hand[]++;
}
}
// for(int i=1;i<=15;i++) printf("%d ",hand[i]);
// printf("\n");
dfs();
printf("%d\n",ans);
}
return ;
}

AC日记——斗地主(dfs)的更多相关文章

  1. AC日记——codevs1688求逆序对

    AC日记--codevs1688求逆序对 锵炬 掭约芴巷 枷锤霍蚣 蟠道初盛 到被他尽情地踩在脚下蹂躏心中就无比的兴奋他是怎么都 ㄥ|囿楣 定要将他剁成肉泥.挫骨扬灰跟随着戴爷这么多年刁梅生 圃鳋 ...

  2. NOIP2015斗地主[DFS 贪心]

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  3. AC日记——寻找道路 洛谷 P2296

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  4. AC日记——接龙游戏 codevs 1051

    1051 接龙游戏  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description 给出了N个单词,已经按长度排好了序.如果 ...

  5. 洛谷P2444 [POI2000]病毒(AC自动机,DFS求环)

    洛谷题目传送门 AC自动机入门--yyb巨佬的博客 AC自动机入手经典好题(虽然年代久远) 有了fail指针,trie树就不是原来的树型结构了,我们可以把它叫做trie图,由父节点向子节点连的边和fa ...

  6. AC日记——传染病控制 洛谷 P1041

    传染病控制 思路: 题目想问的是: 有一棵树: 对于除1外每个深度可以剪掉一棵子树: 问最后剩下多少节点: 题目意思一简单,这个题立马就变水了: 搜索就能ac: 数据有为链的情况,按深度为层次搜索的话 ...

  7. AC日记——联合权值 洛谷 P1351

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  8. [日常摸鱼][POI2000]病毒-Tire图(AC自动机)+dfs

    https://www.luogu.org/problemnew/show/P2444 (没有bzoj权限号T_T) 字符串题对我这种傻逼来说真是太难了x 题意:输入$n$个01组成的模式串串,判断是 ...

  9. AC日记——楼房 codevs 2995

    2995 楼房  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 地平线(x轴)上有n个矩(lou ...

随机推荐

  1. java微信开发(wechat4j)——设置响应微信参数

    设置响应微信参数 wechat4j框架官方文档: https://github.com/sword-org/wechat4j/wiki

  2. JS-取出字符串中重复次数最多的字符并输出

    /** 取出字符串中重复字数最多的字符 */ var words = 'sdfghjkfastgbyhnvdstyaujskgfdfhlaa'; //创建字符串 var word, //单个字符 le ...

  3. css3属性(一)

    圆角效果: border-radius: 5px 4px 3px 2px; /* 四个半径值分别是左上角.右上角.右下角和左下角,顺时针 */ 阴影: box-shadow:X轴偏移量 Y轴偏移量 [ ...

  4. 优化ABAP性能(摘录)

    1.使用where语句不推荐Select * from zflight.Check : zflight-airln = ‘LF’ and zflight-fligh = ‘BW222’.Endsele ...

  5. andriod 用户名和密码

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  6. java多线程系列1--线程实现与调度

    java的重要功能之一就是内部支持多线程,这一系列文章将详细剖析java多线程的基础知识 多线程概述 多线程引入 程序只有一个执行流程,所以这样的程序就是单线程程序. 假如一个程序有多条执行流程,那么 ...

  7. Linux环境变量

    本文地址:http://www.cnblogs.com/archimedes/p/linux-envionment-variables.html,转载请注明源地址. 1.什么是环境变量 bash sh ...

  8. iOS单元测试1

    iOS单元测试1 iOS单元测试分为两种类型的测试: 应用测试.应用程序测试可以检查app的代码组件,比如计算机的算术运算的例子.你可以利用应用程序测试来确保你的UI空间控件保持原有位置,并且你的控件 ...

  9. 【原/转】iOS中非常强大的过滤器:NSPredicate

    在APPLE的官方Demo:UICatalog中实现UISearchBar模糊搜索功能是这么做的: - (void)viewDidLoad { [super viewDidLoad]; self.al ...

  10. NSURLSession/NSURLConnection的上传文件方法(已做了更新)

    最好的学习方法就是 领悟 + 证悟. 此篇文章的理论基础主要是与HTTP网络通信协议相关.为集中精力,可以先把TCP/IP协议这些置之不理,也就是先只关注HTTP的请求和响应的结构.HTTP完整的原理 ...