zoukankan      html  css  js  c++  java
  • P2668 斗地主

    题意:

    给你牌,问你最少几次全部打出去QAQ恶心

    所以,暴力呗。。然而。。各种TLE

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    int T;
    int n;
    int t[20];
    int ans;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline void dfs(int dep)
    {
        for(int i=3;i<=17;i++)
        {
            if(t[i]) break;
            if(i==17)
            {
                ans=min(ans,dep);
                return;
            }
        }
        if(t[16]&&t[17])
        {
            t[16]=t[17]=0;
            dfs(dep+1);
        }
        for(int i=3;i<=14;i++)   //三顺子
            for(int j=i+1;j<=14;j++)
            {
                for(int k=i;k<=j;k++)
                    if(t[k]<3) goto wmy;
                for(int k=i;k<=j;k++)
                    t[k]-=3;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]+=3;
                wmy:;
            }
        for(int i=3;i<=14;i++)   //双顺子
            for(int j=i+2;j<=14;j++)
            {
                for(int k=i;k<=j;k++)
                    if(t[k]<2) goto shit;
                for(int k=i;k<=j;k++)
                    t[k]-=2;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]+=2;
                shit:;
            }
        for(int i=3;i<=14;i++)   //单顺子
            for(int j=i;j<=14;j++)
            {
                for(int k=i;k<=j;k++)
                    if(!t[k]) goto girlfriend;
                for(int k=i;k<=j;k++)
                    t[k]--;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]++;
                girlfriend:;
            }
        for(int i=3;i<=15;i++)    //四带二
        { 
            if(t[i]==4)
            {
                t[i]=0;
                for(int j=3;j<=17;j++)
                {
                    if(t[j])
                    {
                        t[j]--;
                        for(int k=j;k<=17;k++)
                        {
                            if(t[k])
                            {
                                t[k]--;
                                dfs(dep+1);
                                t[k]++;
                            }
                        }
                        t[j]++; 
                    }
                }
                for(int j=3;j<=17;j++)
                {
                    if(t[j]>=2)
                    {
                        t[j]-=2;
                        for(int k=j;k<=17;k++)
                        {
                            if(t[k]>=2)
                            {
                                t[k]-=2;
                                dfs(dep+1);
                                t[k]+=2;
                            }
                        }
                        t[j]+=2; 
                    }
                }
                t[i]=4;
            }
        }
        for(int i=3;i<=15;i++)    //三带二
        { 
            if(t[i]>=3)
            {
                t[i]-=3;
                for(int j=3;j<=15;j++)
                {
                    if(t[j]>=2)
                    {
                        t[j]-=2;
                        dfs(dep+1);
                        t[j]+=2;
                    }
                }
                t[i]+=3;
            }
        }
        for(int i=3;i<=15;i++)    //三带一
        { 
            if(t[i]>=3)
            {
                t[i]-=3;
                for(int j=3;j<=15;j++)
                {
                    if(t[j])
                    {
                        t[j]--;
                        dfs(dep+1);
                        t[j]++;
                    }
                }
                t[i]+=3;
            }
        }
        for(int i=3;i<=15;i++)    //三不带
        { 
            if(t[i]>=3)
            {
                t[i]-=3;
                dfs(dep+1);
                t[i]+=3;
            }
        }
        for(int i=3;i<=15;i++)   //对子
        { 
            if(t[i]>=2)
            {
                t[i]-=2;
                dfs(dep+1);
                t[i]+=2;
            }
        }
    }
    inline void init()
    {
        ans=n;
        memset(t,0,sizeof t);
        for(int i=1;i<=n;i++)
        {
            int x=read();
            int y=read();
            if(x>=3&&x<=13)
                t[x]++;
            else if(x==0)
            {
                if(y==1)
                    t[16]++;
                else
                    t[17]++;
            }
            else 
                t[13+x]++;
        }
    }
    int main()
    {
        T=read();
        n=read();
        while(T--)
        {
            init();
            dfs(0);
            put(ans);
            putchar('
    ');
        }
        olinr ~~(0^_^0)+love_nmr;
    }

    对于单的和双的,耗时太多了QAQ

    所以后来发现了一个桶套桶的贪心做法

    tong[i]代表牌数为i的有几种

    贪心QAQ

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    int T;
    int n;
    int t[20];
    int ans;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int tong[20];
    inline int tanxin()
    {
        int tot=0;
        memset(tong,0,sizeof tong);
        for(int i=3;i<=16;i++)
            tong[t[i]]++;
        while(tong[4]&&tong[2]>=2) 
        {
            tong[4]--;
            tong[2]-=2;
            tot++;
        } 
        while(tong[4]&&tong[1]>=2) 
        {
            tong[4]--;
            tong[1]-=2;
            tot++;
        }
        while(tong[4]&&tong[2]) 
        {
            tong[4]--;
            tong[2]--;
            tot++;
        }
        while(tong[3]&&tong[2]) 
        {
            tong[3]--;
            tong[2]--;
            tot++;
        }
        while(tong[3]&&tong[1]) 
        {
            tong[3]--;
            tong[1]--;
            tot++;
        }
        return tot+tong[1]+tong[2]+tong[3]+tong[4];
    
    }
    inline void dfs(int dep)
    {
        // for(int i=3;i<=17;i++)
        // {
        //     if(t[i]) break;
        //     if(i==17)
        //     {
        //         ans=min(ans,dep);
        //         return;
        //     }
        // }
        if(dep>=ans) return;
        ans=min(ans,dep+tanxin());
        for(int i=3;i<=14;i++)  
        {
            int maxn=i;
            while(t[maxn]>=3&&maxn<=14) maxn++;
            maxn--;
            for(int j=i+1;j<=maxn;j++)
            {
                for(int k=i;k<=j;k++)
                    t[k]-=3;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]+=3;
            }
        }
        for(int i=3;i<=14;i++)  
        {
            int maxn=i;
            while(t[maxn]>=2&&maxn<=14) maxn++;
            maxn--;
            for(int j=i+2;j<=maxn;j++)
            {
                for(int k=i;k<=j;k++)
                    t[k]-=2;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]+=2;
            }
        }
        for(int i=3;i<=14;i++)  
        {
            int maxn=i;
            while(t[maxn]&&maxn<=14) maxn++;
            maxn--;
            for(int j=i+4;j<=maxn;j++)
            {
                for(int k=i;k<=j;k++)
                    t[k]--;
                dfs(dep+1);
                for(int k=i;k<=j;k++)
                    t[k]++;
            }
        }
    }
    inline void init()
    {
        ans=n;
        memset(t,0,sizeof t);
        for(int i=1;i<=n;i++)
        {
            int x=read();
            int y=read();
            if(x>=3&&x<=13)
                t[x]++;
            else if(x==0)
                t[16]++;
            else 
                t[13+x]++;
        }
    }
    int main()
    {
        T=read();
        n=read();
        while(T--)
        {
            init();
            dfs(0);
            put(ans);
            putchar('
    ');
        }
        olinr ~~(0^_^0)+love_nmr;
    }

    再加了点小优化,时间顿时大大减少(虽然加强版过不了

  • 相关阅读:
    21.算法实战---栈
    初见Gnuplot——时间序列的描述
    MATLAB连接MySQL数据库
    用python做些有意思的事——分析QQ聊天记录——私人订制
    遇见蒙特卡洛
    层次分析模型(AHP)及其MATLAB实现
    CPP,MATLAB实现牛顿插值
    CPP&MATLAB实现拉格朗日插值法
    python3爬虫再探之豆瓣影评数据抓取
    R——启程——豆瓣影评分析
  • 原文地址:https://www.cnblogs.com/olinr/p/9561858.html
Copyright © 2011-2022 走看看