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; 
    }
  • 相关阅读:
    javaEE web 系统安装时自定义初始化
    windows 安装绿色版mysql
    myeclipse 安装svn(subeclipsesite)插件
    Xcode连接 Git
    生成16位不重复编码
    百度工程师也犯低级错误(有心还是无意)?
    IBatis 映射文件 sql 中大于、小于等符号转义
    web项目文档总览
    银行卡号的校验
    身份证的校验
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9599282.html
Copyright © 2011-2022 走看看