NOIP2015斗地主题解 7.30考试
问题 B: NOIP2015 斗地主
时间限制: 3 Sec 内存限制: 1024 MB
题目描述
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:
输入
第一行包含用空格隔开的2个正整数T,N,表示手牌的组数以及每组手牌的张数。
输出
共T行,每行一个整数,表示打光第T组手牌的最少次数。
样例输入
1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1
样例输出
3
提示
共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张
这道题为NOIP2015第一天第三题。属于爆搜类,没有任何算法,就是模拟加爆搜。由于有不同种打法,dfs分为好几层,本着先大后小便于剪枝的原则,先出顺子,再带牌,最后散着出。
首先,花色对结果无影响,其次大小王对结果是否有贡献只看是否出现其中之一,出现结果+1即可,未出现就不必管了(吐槽一下题目描述,没说四带二不算俩王,但测试点中确实不带)。还有一点值得注意的是大小顺序,首先是2不算顺子,其次1比3~13都大,因此可以把大小统一减2,1、2改为12、13便于使用。
先预处理出各个数字(以下都为预处理后的数字)的个数,开始分层爆搜。先提前说明各个数组,la[]为各个数字还剩几个没打,num[i]为数量为i的同数字牌还有几个
第一至三层为顺子,它们可以搜索到自己,因为一套牌可以出现多个顺子,至于顺子的长度,从大到小进行枚举,原理见上然后将搜索完的目标再次指向自己,在函数最后向下一层搜索。
第四,五层为带,四层为四带二,要注意是四带二不是四带一,因为这个卡了55%,带对带单都可以,又因为可以同时出四带两个单和四带两个双,因此需要引入一个bool型变量确认该次搜索由哪里传下来,若为上层则四带双和四带单都单独搜索,四带双继续指向本层,bool改变,只搜四带单,三同理。
第五层就是处理散牌了,不解释。
最后膜拜?大犇,有一个剪枝,若到盖层走的步数以比当前最优解大,则直接返回,貌似省了不少时间。
本来就是搜索题,只能说这些了,其实主要还是代码能力和脑洞。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
int t,n,ans=0x7fffffff;
int sum[],la[],num[];
void dfs6(int js){
if(js>=ans)return;
int jj=;
for(int i=;i>=;i--)
jj+=num[i];
ans=min(ans,jj+js);
return;
}
void dfs5(int js,bool pd){ //3 _
if(js>=ans)return;
int nn[];
memcpy(nn,num,sizeof(num));
if(!pd)
{
for(int i=num[];i>=;i--)
{
if(num[]>=i)
{
memcpy(num,nn,sizeof(num));
num[]-=i;
num[]-=i;
dfs5(js+i,);
memcpy(num,nn,sizeof(num));//记得还原,否则判断num[]将会失误。下同。
}
}
}
for(int i=num[];i>=;i--)
{
if(num[]>=i)
{
memcpy(num,nn,sizeof(num));
num[]-=i;
num[]-=i;
dfs6(js+i);
memcpy(num,nn,sizeof(num));
}
}
memcpy(num,nn,sizeof(nn));
dfs6(js);
}
void dfs4(int js,bool pd){ //4 2
if(js>=ans) return;
int nn[];
if(!pd)
{
memset(num,,sizeof(num));
for(int i=;i<=;i++) num[la[i]]++;
memcpy(nn,num,sizeof(num));
for(int i=num[];i>=;i--)
{
if(num[]>=i*)
{
memcpy(num,nn,sizeof(nn));
num[]-=i;
num[]-=i*;
dfs4(js+i,);
memcpy(num,nn,sizeof(nn));
}
}
}
if(pd) memcpy(nn,num,sizeof(num));
for(int i=num[];i>=;i--)
{
if(num[]>=i*)
{
memcpy(num,nn,sizeof(nn));
num[]-=i;
num[]-=i*;
dfs5(js+i,);
memcpy(num,nn,sizeof(nn));
}
}
memcpy(num,nn,sizeof(nn));
dfs5(js,);
}
void dfs3(int js){ //1s
if(js>=ans) return;
int ll[];
memcpy(ll,la,sizeof(la));
for(int l=;l>=;l--)
{
for(int i=;i<=-l+;i++)
{
bool yx=;
for(int j=i;j<=i+l-;j++)
{
if(la[j]<)
{
yx=;
break;
}
}
if(yx)
{
memcpy(la,ll,sizeof(ll));
for(int j=i;j<=i+l-;j++)
{
la[j]-=;
}
dfs3(js+);
memcpy(la,ll,sizeof(ll));
}
}
}
memcpy(la,ll,sizeof(ll));
dfs4(js,);
}
void dfs2(int js){ //2s
if(js>=ans) return;
int ll[];
memcpy(ll,la,sizeof(la));
for(int l=;l>=;l--)
{
for(int i=;i<=-l+;i++)
{
bool yx=;
for(int j=i;j<=i+l-;j++)
{
if(la[j]<)
{
yx=;
break;
}
}
if(yx)
{
memcpy(la,ll,sizeof(ll));
for(int j=i;j<=i+l-;j++)
{
la[j]-=;
}
dfs2(js+);
memcpy(la,ll,sizeof(ll));
}
}
}
memcpy(la,ll,sizeof(ll));
dfs3(js);
}
void dfs1(int js){ //3s
if(js>=ans) return;
int ll[];
memcpy(ll,la,sizeof(la));
for(int l=;l>=;l--)
{
for(int i=;i<=-l+;i++)
{
bool yx=;
for(int j=i;j<=i+l-;j++)
{
if(la[j]<)
{
yx=;
break;
}
} if(yx)
{
memcpy(la,ll,sizeof(ll));
for(int j=i;j<=i+l-;j++)
{
la[j]-=;
}
dfs1(js+);
memcpy(la,ll,sizeof(ll));
}
}
}
memcpy(la,ll,sizeof(ll));
dfs2(js);
}
int main(){
scanf("%d%d",&t,&n);
while(t--)
{
memset(sum,,sizeof(sum));
memset(la,,sizeof(la));
memset(num,,sizeof(num));
ans=0x7fffffff;
int a,b,c,d;
for(int i=;i<=n;i++)
{
int xx,yy;
scanf("%d%d",&xx,&yy);
if(xx==)
xx=;
else if(xx==)
xx=;
else xx-=;
if(xx==-) xx=;
sum[xx]++;
}
memcpy(la,sum,sizeof(sum));
dfs1();
if(sum[]) ans++;
printf("%d\n",ans);
}
//while(1);
return ;
}
NOIP2015斗地主题解 7.30考试的更多相关文章
- BZOJ 4325: NOIP2015 斗地主
4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 684 Solved: 456[Submit][Status] ...
- NOIP2015 斗地主(搜索+剪枝)
4325: NOIP2015 斗地主 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 270 Solved: 192[Submit][Status] ...
- 【BZOJ4325】NOIP2015 斗地主 搜索+剪枝
[BZOJ4325]NOIP2015 斗地主 Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗 ...
- NOIP2015斗地主[DFS 贪心]
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- [补档][NOIP2015] 斗地主
[NOIP2015] 斗地主 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=2106 INPUT 第一行包含用空格隔开的2个正整数Tn,表示手 ...
- LOJ2422 NOIP2015 斗地主 【搜索+贪心】*
LOJ2422 NOIP2015 斗地主 LINK 题目大意很简单,就是问你斗地主的一分手牌最少多少次出完 然后我们发现对于一种手牌状态,不考虑顺子的情况是可以贪心做掉的 然后我们直接枚举一下顺子出牌 ...
- 2106. [NOIP2015] 斗地主
2106. [NOIP2015] 斗地主 ★★★☆ 输入文件:landlords.in 输出文件:landlords.out 简单对比 时间限制:2 s 内存限制:1025 M ...
- 题解【洛谷P2668】[NOIP2015]斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的 $ A $ 到 $ K $ 加上大小王的共 $ 54 $ 张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据 ...
- 【NOIP2015】斗地主 题解(DFS+贪心)
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的AAA到KKK加上大小王的共545454张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下: ...
随机推荐
- 【全面解禁!真正的Expression Blend实战开发技巧】序章
原文:[全面解禁!真正的Expression Blend实战开发技巧]序章 从silverlight2开始我也和大家一样一直在跟随微软的脚步,从sl2~sl4一步一步过来,总结了不少心得体会.由于各种 ...
- 理解 node.js 的事件循环
node.js 的第一个基本观点是,I/O 操作是昂贵的: 目前的编程技术最大的浪费来自等待 I/O 操作的完成.有几种方法可以解决这些对性能的影响(来自Sam Rushing): 同步:依次处理单个 ...
- 处理 Windows Phone 应用中的“后退”按钮 (XAML)
与电脑不同,所有 Windows Phone 设备都有“后退”按钮,它允许用户在应用的页面之间向后导航.如果用户在转到应用的第一页时再次按“后退”按钮,操作系统会挂起你的应用并将用户导航到应用启动前的 ...
- Oracle 存储过程创建及调用
--------创建存储过程------- create or replace procedure TestSPas begin update table_name set CREATE_TIMEST ...
- ORA-19625: error identifying file XXXXX
在RMAN备份全库的时候,将归档日志一同进行备份,结果报如下错误,可以看到是无法获得对应归档日志的报错: RMAN: ========================================= ...
- WPF 设置只能运行一个实例
codereview上的帖子 https://codereview.stackexchange.com/questions/20871/single-instance-wpf-application ...
- wp8.1之拍照(获取焦点,使用后置摄像头)
wp8.1 没有像wp8一样直接用启动器开启摄像头,他要开启摄像头要借助CaptureElement呈现来自捕获设备(如照相机或网络摄像机)的流.今天讲讲如何打开摄像头,获取焦点,以及拍照.废话不多说 ...
- Android View 滚动边界的测量
最近一直在用Android TV的RecyclerView,实现视频搜索列表卡片的滚动显示,由于采用了双排滚动,打破了系统默认的单排滚动,且每一屏幕显示10个完整卡片5个半漏边卡片,每个完整卡片的左下 ...
- 使用网盘(Dropbox/Google Drive)同步Git仓库
还在使用老掉牙的U盘搬运代码(文件)的方式,从一台机器上复制后,粘贴到另一台机器上?太Out了.使用Github 倒是一个非常不错的替代方法.但无论是基于什么理由都有可能不想把代码公开(毕竟Githu ...
- Aria2在Windows上如何安装配置使用
一.下载所需的软件 二.安装与使用 三.Aria2的额外内容 四.Aria2的使用 五.Aria2与其它插件配合使用 一.下载所需的软件 可以从一下地址获取最新版本 GitHub: https://g ...