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('\n');
    }
    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('\n');
    }
    olinr ~~(0^_^0)+love_nmr;
}

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

猜你喜欢

转载自www.cnblogs.com/olinr/p/9561858.html
今日推荐