还记得那道我只用特判得了30分的“斗地主”吗?

我今天脑抽打算把它改A掉。为什么不用这大好时光去干些更有意义的事

于是我就挖了这个坑。

题解:

题目链接:P2668 斗地主

本题就是一道大搜索。按照顺序,先搜顺子、双顺子、三顺子;再搜三张牌、四张牌。

注意顺子的回溯部分,以及有四张同点数牌的时候也可以只出三张。

基本思路除了搜索之外就是贪心,优先将搜出来的多张牌一起出。

我是将双王分开存储的,防止三/四带对的时候将双王带上。

最后结束出单牌的时候,记得将对子和双王一起出。

这段代码过不了加强版数据,需要将贪心的思想换成dp。

源码有注释。

//MiserWeyte is now "mzWyt"
#include <bits/stdc++.h>
using namespace std;
int T, n, num, ul, ans;
int card[20]; // 存储每种牌张数 void power_sol(){ // 暴力解决n<=4
if(n==2){
int c1, c2;
while(T--){
scanf("%d%d%d%d", &c1, &ul, &c2, &ul);
if(c1==c2) printf("1\n");
else printf("2\n");
}
return;
}
if(n==3){
int c1, c2, c3;
while(T--){
scanf("%d%d%d%d%d%d", &c1, &ul, &c2, &ul, &c3, &ul);
if(c1==c2 && c2==c3) printf("1\n");
else if(c1 == c2 && c2 != c3) printf("2\n");
else if(c1 != c2 && c2 == c3) printf("2\n");
else if(c1 == c3 && c2 != c3) printf("2\n");
else printf("3\n");
}
return;
}
if(n==4){
int c1, c2, c3, c4;
while(T--){
scanf("%d%d%d%d%d%d%d%d", &c1, &ul, &c2, &ul, &c3, &ul, &c4, &ul);
if(c1==c2&&c2==c3&&c3==c4) printf("1\n");
else if(c1==c2&&c2==c3&&c3!=c4) printf("1\n");
else if(c1==c2&&c2!=c3&&c2==c4) printf("1\n");
else if(c1!=c2&&c2==c3&&c3==c4) printf("1\n");
else if(c1==c2&&c3==c4) printf("2\n");
else if(c1==c3&&c2==c4) printf("2\n");
else if(c1==c4&&c2==c3) printf("2\n");
else if(c1==c2||c1==c3||c1==c4||c2==c3||c2==c4||c3==c4) printf("3\n");
else printf("4\n");
}
return;
}
} void init(){
memset(card, 0, sizeof(card)); // 初始化清空card数组
ans = n; // 初始化ans为n(不存在比全出单张更劣的方案) } void dbg(){ // 调试,输出当前所有牌
cout << endl;
for(int i=0; i<=14; i++){
cout << i << '\t' << card[i] << '\n';
}
cout << endl;
} void dfs(int dep){
if(dep > ans) return; // 剪枝
int l; // 当前顺子长度
l = 0;
for(int i=3; i<=14; i++){ // 搜索单顺子
if(card[i]) l ++;
else l = 0;
if(l >= 5){ // 长度达到顺子
for(int j=i-l+1; j<=i; j++) card[j] --;
// dbg();
dfs(dep + 1);
for(int j=i-l+1; j<=i; j++) card[j] ++;
}
}
l = 0;
for(int i=3; i<=14; i++){ // 搜索双顺子
if(card[i] >= 2) l ++;
else l = 0;
if(l >= 3){ // 长度达到双顺子
for(int j=i-l+1; j<=i; j++) card[j] -= 2;
dfs(dep + 1);
for(int j=i-l+1; j<=i; j++) card[j] += 2;
}
}
l = 0;
for(int i=3; i<=14; i++){ // 搜索三顺子
if(card[i] >= 3) l ++;
else l = 0;
if(l >= 2){ // 长度达到三顺子
for(int j=i-l+1; j<=i; j++) card[i] -= 3;
dfs(dep + 1);
for(int j=i-l+1; j<=i; j++) card[i] += 3;
}
}
for(int i=2; i<=14; i++){ // 搜三张牌或四张牌
if(card[i] >= 3){ //三带一张或一对
card[i] -= 3;
for(int j=0; j<=14; j++){
if(!card[j] || j == i) continue;
if(card[j]){
card[j] --;
dfs(dep + 1);
card[j] ++;
}
if(card[j] >= 2){
card[j] -= 2;
dfs(dep + 1);
card[j] += 2;
}
}
card[i] += 3;
if(card[i] == 4){ // 四带两张或两对
card[i] -= 4;
for(int j=0; j<14; j++){ //带两张
if(!card[j] || j == i) continue;
card[j] --;
for(int k=0; k<14; k++){
if(!card[k] || k == j || k == i) continue;
card[k] --;
dfs(dep + 1);
card[k] ++;
}
card[j] ++;
}
for(int j=0; j<14; j++){ //带两对
if(card[j] < 2 || j == i) continue;
card[j] -= 2;
for(int k=0; k<14; k++){
if(card[k] < 2 || k == j || k == i) continue;
card[k] -= 2;
dfs(dep + 1);
card[k] += 2;
}
card[j] += 2;
}
card[i] += 4;
}
}
} for(int i=0; i<=14; i++){ // 把剩余的牌打出
if(card[i]) dep ++; // 一次性打出所有相同点数的牌
if(card[i] >= 3) return; // 如果有三张牌或四张牌没出,一定不是最优
}
if(card[0] && card[1]) dep --; // 双王可以同时打出
// if(dep < ans) dbg();
ans = ans < dep ? ans : dep; // ans取最小
} void input(){
for(int i=0; i<n; i++){
scanf("%d%d", &num, &ul); // 花色并用不到(useless)
if(num == 1) num = 14; // 由于A排在K后面,14存储A
if(num == 0 && ul == 2) num = 1; // 双王分开存储,防止被算成一对
card[num] ++;
}
}
void work(){
if(n <= 4){ // 暴力
power_sol();
return;
}
while(T--){
init();
input();
// dbg();
dfs(0);
printf("%d\n", ans);
}
}
int main(){
cin >> T >> n;
work();
return 0;
}

更新记录


记录一下,从10.31 16:32 开始改这道题。

upd 10.31 18:45:吃完饭瞅了一下之前模拟赛的时候写炸的搜索,(已经看不懂了

upd 10.31 22:16:这个月内看来是做不完了(笑 各位Happy Halloween

upd 11.1 14:57:下午翘课来机房。听取WA声一片。重写。

upd 11.3 13:19:咕咕咕(搜索思路错了 重写

upd 11.3 21:47:我过了!我过了!(作死提交了下增强数据版)(WA+TLE 80pts)(“fxxk”)

Luogu P2668 斗地主(NOIP2015)的更多相关文章

  1. 洛谷P2668 斗地主 [NOIP2015]

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

  2. Luogu 2540 斗地主增强版(搜索,动态规划)

    Luogu 2540 斗地主增强版(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游 ...

  3. 洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]

    P2668 斗地主 326通过 2.6K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举NOIp提高组2015 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 出现未知错误是说梗啊 ...

  4. 题解【洛谷P2668】[NOIP2015]斗地主

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

  5. [NOIP2015] 提高组 洛谷P2668 斗地主

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

  6. 洛谷P2668斗地主(搜索)noip2015

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

  7. 洛谷—— P2668 斗地主

    https://www.luogu.org/problem/show?pid=2668 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...

  8. 斗地主 (NOIP2015 Day1 T3)

    斗地主 张牌,因为它可以连在K后, 总体思路为 先出炸弹和四带二 再出三带一 再把对牌和单牌出完 记录并更新Answer,后枚举顺子,并继续向下搜索. 注意:弄明白题意,题目描述不太清楚....另外, ...

  9. 斗地主[NOIP2015]

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

随机推荐

  1. 判断日期是否为法定节假日的API接口与示例函数

    需要判定某日期是否为法定节假日,由于国家的节假日每年都在变动,所以使用接口判定是必要的.可惜的是,这样的接口并不多,在此汇总三个: http://tool.bitefu.net/jiari/ http ...

  2. uC/OS-III 任务详解(四)

    uC/OS系统的任务一般都放在最开始介绍,我放在第四章主要是对模糊的概念作清晰的讲解. 从用户的角度来看,uC/OS-III 中的任务可以分为5 种状态,分别是休眠态.就绪态.运行态.挂起态和中断态, ...

  3. http转换为https

    1.下载ssl 证数 百度ssl 证数都有 其中以便宜ssl为例子 注册登陆 选择免费版 可以使用3个月: 申请过程中需要检测该域名是否为本人所有 ,所以邮箱检测或者域名配置 很简单检测就好了: 验证 ...

  4. 自创ant-design-pro组件

    ant design蚂蚁金服基于react打造的一个服务于企业级产品的UI框架.而ant design pro呢?就是基于Ant Design这个框架搭建的中后台管理控制台的脚手架. 话不多说,今天给 ...

  5. redis mysql 连接池 之 golang 实现

    1 mysql 连接池代码 package lib import ( "database/sql" "fmt" "strconv" &quo ...

  6. 1.Eclipse下载、常用配置、快捷键

    Eclipse官网下载:https://www.eclipse.org/downloads/packages/ 自动补全 位置:Eclipse——Window——Perferences——Java—— ...

  7. kubernetes垃圾回收器GarbageCollector源码分析(一)

    kubernetes版本:1.13.2 背景 由于operator创建的redis集群,在kubernetes apiserver重启后,redis集群被异常删除(包括redis exporter s ...

  8. Zabbix安装与简单配置

    目录 0. 前言 1. 安装 1.1 准备安装环境 1.1.1 下载安装包 1.1.2 修改文件配置 1.2 开始安装 2. 实验环境 2.1 简易拓扑图 2.2 基本配置 3. 配置 0. 前言 不 ...

  9. Bitset改进你的程序质量

    1:Bitset介绍 BitSet 是用于存储二进制位和对二进制进行操作的 Java 数据结构, 此类实现了一个按需增长的位向量.位 set 的每个组件都有一个 boolean 值.用非负的整数将 B ...

  10. 奇淫异巧之 PHP 后门

    整理大部分来源信安之路 对于隐蔽来说,有以下几点要素: 1.熟悉环境,模拟环境,适应环境,像一只变色龙一样隐藏 2.清除痕迹,避免运维发现 3.避免后门特征值被 D 盾等工具检测到 姿势 一般过狗思路 ...