zoukankan      html  css  js  c++  java
  • NOIP2015斗地主(搜索+模拟+贪心)

    %%%Luan

    题面就不说了,和斗地主一样,给一组牌,求最少打几次。

    注意一点,数据随机,这样我们瞎搞一搞就可以过,虽然直接贪心可以证明是错的。

    枚举方法,每次搜索按照(三顺子>二顺子>普通顺子)枚举一个进入下一层搜索。

    在每层搜索中我们都要枚举打其他牌的方法,用贪心的结果+顺子数来更新答案。

    具体方法是(想象你手里有这么多牌你该怎么打),枚举四代二,四代一,三代二,三代一,对和单。

    注意我要带的必须是恰好两个或一个,不然会被随机数据hack。。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int di[20],cnt[20],ans,n,t,a,b;
    inline int counting(){
        int jians=0;
        for(int i=1;i<=14;++i)di[i]=cnt[i];
        for(int i=1;i<=13;++i)
          if(di[i]>=4)
            for(int j=1;j<=14;++j)
              if(i!=j&&di[j]==2&&di[i]>=4)
                for(int k=j+1;k<=14;++k)
                  if(k!=i&&di[k]==2){di[i]-=4;di[j]-=2;di[k]-=2;jians++;break;}
        for(int i=1;i<=13;++i)
          if(di[i]>=4)
            for(int j=1;j<=14;++j)
              if(i!=j&&di[j]==1&&di[i]>=4)
                for(int k=j+1;k<=14;++k)
                  if(k!=i&&di[k]==1){di[i]-=4;di[j]--;di[k]--;jians++;break;} 
        for(int i=1;i<=13;++i)
          if(di[i]>=4)
            for(int j=1;j<=14;++j)
              if(i!=j&&di[j]==2){di[j]-=2;di[i]-=4;jians++;break;}
        for(int i=1;i<=13;++i)while(di[i]>=4)jians++,di[i]-=4;
        for(int i=1;i<=13;++i)
          if(di[i]>=3)
            for(int j=1;j<=14;++j)
              if(i!=j&&di[j]==2){if(di[i]<3)break;di[i]-=3;di[j]-=2;jians++;}
        for(int i=1;i<=13;++i)
          if(di[i]>=3)
            for(int j=1;j<=14;++j)
              if(i!=j&&di[j]==1){if(di[i]<3)break;di[j]--;di[i]-=3;jians++;} 
        for(int i=1;i<=13;++i)while(di[i]>=3)jians++,di[i]-=3;
        for(int i=1;i<=14;++i)while(di[i]>=2)jians++,di[i]-=2;
        for(int i=1;i<=14;++i)while(di[i])jians++,di[i]--;
        return jians;      
    } 
    void dfs(int deep){
        if(deep>=ans)return;
        for(int i=1;i<=14;++i){
            if(cnt[i])break;
            if(i==14){
                ans=deep;return;
            }
        }
    //    for(int i=1;i<=14;++i)cout<<cnt[i]<<" ";cout<<"   ";
        int cmd=counting();//cout<<cmd<<endl;
        if(cmd+deep<ans)ans=cmd+deep;
        for(int i=1;i<=10;++i)if(cnt[i]>=3)
          for(int j=i+1;j<=12;++j){
              bool tag=0;
              for(int k=i;k<=j;++k)
                  if(cnt[k]<3){
                      tag=1;
                    break;
                   }
              if(tag)break;
             for(int k=i;k<=j;++k)cnt[k]-=3;
             dfs(deep+1);
             for(int k=i;k<=j;++k)cnt[k]+=3;
           }
        for(int i=1;i<=10;++i)if(cnt[i]>=2)
          for(int j=i+2;j<=12;++j){
               bool tag=0;
               for(int k=i;k<=j;++k)
                   if(cnt[k]<2){
                       tag=1;
                       break;
                   }
            if(tag)break;
            for(int k=i;k<=j;++k)cnt[k]-=2;
            dfs(deep+1);
            for(int k=i;k<=j;++k)cnt[k]+=2;
          }
        for(int i=1;i<=8;++i)
          for(int j=i+4;j<=12;++j){
              bool tag=0;
              for(int k=i;k<=j;++k)
                if(!cnt[k]){
                      tag=1;
                      break;
                }
            if(tag)break;
            for(int k=i;k<=j;++k)--cnt[k];
            dfs(deep+1);
            for(int k=i;k<=j;++k)++cnt[k];
          }
    }
    int main(){
        scanf("%d%d",&t,&n);
        while(t--){
            memset(cnt,0,sizeof(cnt));
            for(int i=1;i<=n;++i){
                scanf("%d%d",&a,&b);
                if(a>=3||a<=13)cnt[a-2]++;
                if(a==0)cnt[14]++;
                if(a==1)cnt[12]++;
                if(a==2)cnt[13]++; 
            }
            ans=0x3f3f3f3f;
            dfs(0); 
            printf("%d
    ",ans); 
        }
        return 0; 
    }
  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9599282.html
Copyright © 2011-2022 走看看