7.30考试(第一发博文)

  第一篇博文献给NOIP2015斗地主。

  这道题为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[14],la[14],num[5];
void dfs6(int js){
    if(js>=ans)return;
    int jj=0;
    for(int i=4;i>=1;i--)
        jj+=num[i];
    ans=min(ans,jj+js);
    return;
}
void dfs5(int js,bool pd){ //3 _
    if(js>=ans)return;
    int nn[5];
    memcpy(nn,num,sizeof(num));
    if(!pd)
    {
        for(int i=num[3];i>=1;i--)
        {
            if(num[2]>=i)
            {
                memcpy(num,nn,sizeof(num));
                num[3]-=i;
                num[2]-=i;
                dfs5(js+i,1);
                memcpy(num,nn,sizeof(num));//记得还原,否则判断num[]将会失误。下同。
            }
        }
    }
    for(int i=num[3];i>=1;i--)
    {
        if(num[1]>=i)
        {
            memcpy(num,nn,sizeof(num));
            num[3]-=i;
            num[1]-=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[5];
    if(!pd)
    {
        memset(num,0,sizeof(num));
        for(int i=1;i<=13;i++) num[la[i]]++;
        memcpy(nn,num,sizeof(num));
        for(int i=num[4];i>=1;i--)
        {
            if(num[2]>=i*2)
            {
                memcpy(num,nn,sizeof(nn));
                num[4]-=i;
                num[2]-=i*2;
                dfs4(js+i,1);
                memcpy(num,nn,sizeof(nn));
            }
        }
    }
    if(pd) memcpy(nn,num,sizeof(num));
    for(int i=num[4];i>=1;i--)
    {
        if(num[1]>=i*2)
        {
            memcpy(num,nn,sizeof(nn));
            num[4]-=i;
            num[1]-=i*2;
            dfs5(js+i,0);
            memcpy(num,nn,sizeof(nn));
        }
    }
    memcpy(num,nn,sizeof(nn));
    dfs5(js,0);
}
void dfs3(int js){    //1s
    if(js>=ans) return;
    int ll[14];
    memcpy(ll,la,sizeof(la));
    for(int l=12;l>=5;l--)
    {
        for(int i=1;i<=12-l+1;i++)
        {
            bool yx=1;
            for(int j=i;j<=i+l-1;j++)
            {
                if(la[j]<1)
                {
                    yx=0;
                    break;
                }
            }
            if(yx)
            {
                memcpy(la,ll,sizeof(ll));
                for(int j=i;j<=i+l-1;j++)
                {
                    la[j]-=1;
                }
                dfs3(js+1);
                memcpy(la,ll,sizeof(ll));
            }
        }
    }
    memcpy(la,ll,sizeof(ll));
    dfs4(js,0);
}
void dfs2(int js){   //2s
    if(js>=ans)    return;
    int ll[14];
    memcpy(ll,la,sizeof(la));
    for(int l=11;l>=3;l--)
    {
        for(int i=1;i<=12-l+1;i++)
        {
            bool yx=1;
            for(int j=i;j<=i+l-1;j++)
            {
                if(la[j]<2)
                {
                    yx=0;
                    break;
                }
            }
            if(yx)
            {
                memcpy(la,ll,sizeof(ll));
                for(int j=i;j<=i+l-1;j++)
                {
                    la[j]-=2;
                }
                dfs2(js+1);
                memcpy(la,ll,sizeof(ll));
            }
        }
    }
    memcpy(la,ll,sizeof(ll));
    dfs3(js);
}
void dfs1(int js){  //3s
    if(js>=ans) return;
    int ll[14];
    memcpy(ll,la,sizeof(la));
    for(int l=7;l>=2;l--)
    {
        for(int i=1;i<=12-l+1;i++)
        {
            bool yx=1;
            for(int j=i;j<=i+l-1;j++)
            {
                if(la[j]<3)
                {
                    yx=0;
                    break;
                }
            }

            if(yx)
            {
                memcpy(la,ll,sizeof(ll));
                for(int j=i;j<=i+l-1;j++)
                {
                    la[j]-=3;
                }
                dfs1(js+1);
                memcpy(la,ll,sizeof(ll));
            }
        }
    }
    memcpy(la,ll,sizeof(ll));
    dfs2(js);
}
int main(){
    scanf("%d%d",&t,&n);
while(t--)
{
    memset(sum,0,sizeof(sum));
    memset(la,0,sizeof(la));
    memset(num,0,sizeof(num));
    ans=0x7fffffff;
    int a,b,c,d;
    for(int i=1;i<=n;i++)
    {
        int xx,yy;
        scanf("%d%d",&xx,&yy);
        if(xx==1)
            xx=12;
        else if(xx==2)
            xx=13;
        else xx-=2;
        if(xx==-2) xx=0;
        sum[xx]++;
    }
    memcpy(la,sum,sizeof(sum));
    dfs1(0);
    if(sum[0]) ans++;
    printf("%d\n",ans);
}
    //while(1);
    return 0;
}
时间: 2024-09-30 19:16:42

7.30考试(第一发博文)的相关文章

7.30考试password

先说地球人都看得出来的,该数列所有数都是p的斐波那契数列中所对应的数的次幂,所以一开始都以为是道水题,然而斐波那契数列增长很快,92以后就爆long long ,所以要另谋出路,于是乎向Ren_ivan大犇学了扩展欧拉定理:(a^b)%p=(a^(b%φ(p)))%p不要问我为什么,我也不会证. 所以这道题就变成简单的数学题了,首先筛出sqpt(1<<31)以内的素数,不必担心复杂度,线筛还是挺快的.然后针对每一个q求出它的欧拉函数,再通过矩阵快速幂求出对应的斐波那契数列,再用快速幂最终处理即

6.30考试

点名[题目描述]在J班的体育课上, 同学们常常会迟到几分钟, 但体育老师的点名却一直很准时.老师只关心同学的身高, 他会依次询问当前最高的身高, 次高的身高, 第三高的身高,等等.在询问的过程中,会不时地有人插进队伍里.你需要回答老师每次的询问.[输入格式]第一行两个整数 n m,表示先后有 n 个人进队,老师询问了 m 次第二行 n 个整数,第 i 个数 $A_i$ 表示第 i 个进入队伍的同学的身高为 $A_i$第三行 m 个整数,第 j 个数 $B_j$ 表示老师在第 $B_j$ 个同学进

2019.12.30考试总结

T1摆棋子 看到这么多的限制,第一直觉就是网络流,最小费用最大流不能做,因为把棋子代价看成1后最大流的条件并不好满足. 注意到每一行每一列都有一个最小限制,对应到网络流上就是流的下界,整体跑一个有下界的最小流就可以了. #include<iostream> #include<cstring> #include<cstdio> #include<queue> #define LL long long #define DB double using namesp

Security+认证考试经验分享——备考篇(二)

考点: 预约的地点可以联系预约老师,在VUE官网上也可以查询到所在省份具体考点位置,因为Google地图的原因,所以不能更直接看到地理位置,除非- 因为我是第一次参与这种类型的考试,提前去考场蹲了点,我觉得这很有必要,当天况且不说路况,找不着考点会影响心情.考场我是在一间全封闭小屋子,里面有5台机考,大家都考不同的项目,时间也不一致,所以做自己的,不要受别人影响.监考老师在外面通过摄像头监考,桌上提供画板及马克笔,画板写满可以举手示意更换,耳塞好像得向老师说明才进行发放,建议索要.询问过监考老师

中科院 2014年工程硕士入学专业课笔试考场安排

考试时间:2015年1月11日   上午8:30-11:30考试地点:中国科学院大学玉泉路教学园区,教学楼2-6层.  考生请于8:10携带GCT准考证及本人身份证进入玉泉路校区教学楼考场,考试开始30分钟后,迟到者不准进入考场.      第一考场:信号与系统教学楼204教室 序号 准考证号 姓名 1 14110852405225 叶茜 2 14110852702206 张珂 3 14110852708818 张乐 4 14110852804822 张立梅 5 14110852507816 张

Python3基础 类的组合 把类的实例化放到一个新类里面

镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.------------------------------------------ code: class Girls: def __init__(self,num): self.num=num class OurClass: #组合,其他类的实例化,在这里类的实例化中进行 def __init__(self,boyNum,girlNum): self.boys=Boys

基于word分词提供的文本相似度算法来实现通用的网页相似度检测

实现代码:基于word分词提供的文本相似度算法来实现通用的网页相似度检测 运行结果: 检查的博文数:128 1.检查博文:192本软件著作用词分析(五)用词最复杂99级,相似度分值:Simple=0.968589 Cosine=0.955598 EditDistance=0.916884 EuclideanDistance=0.00825 ManhattanDistance=0.001209 Jaccard=0.859838 JaroDistance=0.824469 JaroWinklerDi

css基础 一个class属性给两个名字(实用技巧)

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut

HoneyDrive_3基础学习

20161219 08:51--09:30 这篇博文记录oneyDrive_3_Royal_Jelly(1)系统应用整体的简介和(2)初期准备或相关具体功能的介绍说明,和(3)基本使用或基础理论. 一.系统应用整体的简介 参考: http://bruteforce.gr/honeydrive-3-royal-jelly-edition.html HoneyDrive is the premier honeypot Linux distro. It is a virtual appliance (