斗地主 (NOIP2015 Day1 T3)

            斗地主

思路 :读入时注意将A作为第14张牌,因为它可以连在K后,

总体思路为 先出炸弹和四带二 再出三带一 再把对牌和单牌出完 记录并更新Answer,后枚举顺子,并继续向下搜索。

注意:弄明白题意,题目描述不太清楚。。。。另外,我觉的牌的花色只是能用来区分大小王。另外在整顺子之前也可以用贪心来搞其他类似四带二,三带一等的牌

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int Max = 20;
int T, N, Answer ;
int card [Max];
int Count [Max];
void DFS (int X)
{
    if (X > Answer ) return;
    int rest = 0;
    memset (Count, 0, sizeof (Count));
    for (int i = 0; i <= 14; i++)
        Count [card[i]]++;
    for (; Count [4]; )
    {
        Count [4]--;           //炸弹
        rest++;
        if (Count [2] >= 2)    //判断能不能带2
            Count [2] -= 2;
        else if (Count [1] >= 2)
            Count [1] -= 2;
    }
    for (; Count [3]; )
    {
        Count [3]--;          //三张牌
        rest++;
        if (Count [2])         //能不能带一
            Count [2]--;
        else if (Count [1])
            Count [1]--;
    }
    if (card [0] && card [1] && Count [1] >= 2)    //看看剩下的单牌有没有王炸
        rest--;
    rest += Count [1] + Count [2];
    Answer = min (rest + X, Answer );
    for (int i = 3, j; i <= 14; ++i)         //单顺子
    {
        for (j = i; card [j] && j <= 14; ++j)
        {
            card [j]--;
            if (j - i + 1 >= 5)        //如果剩下的牌多于五张 ,则向下搜索
                DFS (X + 1);
        }
        for (; j > i; )
            card [--j]++;
    }
    for (int i = 3, j; i <= 15; ++i)        //双顺子
    {
        for (j = i; card [j] >= 2 && j <= 14; ++j)
        {
            card [j] -= 2;
            if (j - i + 1 >= 3)
                DFS(X + 1);
        }
        for (; j > i; )
            card [--j] += 2;
    }
    for (int i = 3, j; i <= 15; ++i)     // 三顺子
    {
        for (j = i; card [j] >= 3 && j <= 14; ++j)
        {
            card [j] -= 3;
            if (j - i + 1 >= 2)
                DFS (X + 1);
        }
        for (; j>i;)
            card [--j] += 3;
    }
}
int main()
{
    cin >> T >> N;
    int A, B;
    while (T--)
    {
        memset (card, 0, sizeof (card));
        Answer = N;
        for (int i = 1; i <= N; i++)
        {
            cin >> A >> B;
            if (A == 0) card [B - 1]++;    //王 要分开存 ,因为他们不能组成对子  ,不能当对牌出
            else if (A == 1) card [14]++;
            else card [A]++;
        }
        DFS (0);
        cout << Answer << endl;
    }
    return 0;
}

时间: 2024-11-03 21:07:16

斗地主 (NOIP2015 Day1 T3)的相关文章

【NOIP2015 DAY1 T3 】斗地主(landlords)

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

Day1: T3 bfs T4 树形DP

T3:BFS 回看了一下Day1的T3...感觉裸裸的BFS,自己当时居然没有看出来... 同时用上升和下降两种状态bfs即可 这一题还要注意一个细节的地方,就是题目要求的是求往返的最优解 k=min(d[上升],d[下降]); ans=min(2*k+1,d1[]+d2[]); 输出ans..这个地方需要理解: 其余的照bfs模板打即可:

洛谷P2668 斗地主 [NOIP2015]

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

斗地主[NOIP2015]

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

东方14模拟赛之noip2015/day1/3/神奇的幻方

总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  128000kB 描述 幻方是一种很神奇的N*N 矩阵:它由数字 1,2,3, … …,N*N 构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将 1 写在第一行的中间. 之后,按如下方式从小到大依次填写每个数K(K= 2,3, …,N*N ): 若 (K−1) 在第一行但不在最后一列,则将K填在最后一行,(K−1) 所在列的右一列: 若 (K−1) 在最

洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1

信息传递 NOIP2015 day1 T2

题文: 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入共2行. 第1行包含1个正整数n表示n个人. 第2行包含n个用空

济南学习 Day1 T3 pm

[问题描述]小 Q 对计算几何有着浓厚的兴趣.他经常对着平面直角坐标系发呆,思考一些有趣的问题.今天,他想到了一个十分有意思的题目:首先,小 Q 会在x轴正半轴和y轴正半轴分别挑选??个点.随后,他将x轴的点与y轴的点一一连接,形成??条线段,并保证任意两条线段不相交.小 Q 确定这种连接方式有且仅有一种.最后,小 Q 会给出m个询问.对于每个询问,将会给定一个点P(Px ,Py),请回答线段 OP 与m条线段会产生多少个交点?小 Q 找到了正在钻研数据结构的你,希望你可以帮他解决这道难题.[输

【NOIP 2014 DAY1 T3】飞扬的小鸟(DP)

题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败. 为了简化问题,我们对游戏规则进行了简化和改编: 游戏界面是一个长为n ,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度). 小鸟始终在游戏界面内移动.小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成. 小鸟每个单位时间沿横坐标方向右移的距离为1 ,竖直移动