P2668 斗地主

P2668 斗地主


这题炒鸡休闲的!

正解:暴力DFS+最优性剪枝

代码1:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define re register  
int n;
int s[105];
int bot[105]={0};
int cbo[105];
bool flag;
int start;
int ans=2147483647;
int cal1(char c){
    if(c=='1') return 12;
    if(c=='3') return 1;
    if(c=='4') return 2;
    if(c=='5') return 3;
    if(c=='6') return 4;
    if(c=='7') return 5;
    if(c=='8') return 6;
    if(c=='9') return 7;
    if(c=='2') return 13;
}
int cal2(char a,char b){
    if(a=='0'&&b=='1') return 14;//Big King
    if(a=='0'&&b=='2') return 15;//Small King
    if(a=='1'&&b=='0') return 8;
    if(a=='1'&&b=='1') return 9;
    if(a=='1'&&b=='2') return 10;
    if(a=='1'&&b=='3') return 11;
}
bool check(){
    for(re int i=1;i<=15;i++) if(bot[i]!=0) return 0;
    return 1;
}
int T;
void print(){
    for(re int i=1;i<=15;i++) printf("%d ",bot[i]);
    printf("\n");
}
inline void dfs(int step){
    //print();
//    cout<<step<<endl;
    if(flag==1) return;
    
    if(step>=ans) return;
    if(check()){
        ans=step;
        return;
    }
    for(re int i=n;i>=5;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=15) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<1) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]--;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]++;
        } 
    } 
    for(re int i=n;i>=3;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=15) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<2) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]-=2;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]+=2;
        } 
    } 
    for(re int i=n;i>=2;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=15) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<3) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]-=3;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]+=3;
        } 
    } 
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<1) continue;
                bot[i]-=4;
                bot[j]--;
                bot[k]--;
                dfs(step+1);
                bot[i]+=4;
                bot[j]++;
                bot[k]++;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<2) continue;
                bot[i]-=4;
                bot[j]-=2;
                bot[k]-=2;
                dfs(step+1);
                bot[i]+=4;
                bot[j]+=2;
                bot[k]+=2;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            bot[i]-=3;
            bot[j]--;
            dfs(step+1);
            bot[i]+=3;
            bot[j]++;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=3;
            bot[j]-=2;
            dfs(step+1);
            bot[i]+=3;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=4;
            bot[j]-=2;
            dfs(step+1);
            bot[i]+=4;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<4) continue;
            bot[i]-=4;
            bot[j]-=4;
            dfs(step+1);
            bot[i]+=4;
            bot[j]+=4;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]>3){
            bot[i]-=4;
            dfs(step+1);
            bot[i]+=4;
        }
        if(bot[i]>2){
            bot[i]-=3;
            dfs(step+1);
            bot[i]+=3;
        }
        if(bot[i]>1){
            bot[i]-=2;
            dfs(step+1);
            bot[i]+=2;
        }
        if(bot[i]>0){
            bot[i]--;
            dfs(step+1);
            bot[i]++;
        }
    }
    if(bot[14]==1&&bot[15]==1){
        bot[14]--,bot[15]--;
        dfs(step+1);
        bot[14]++,bot[15]++;
    }
}
int main(){
    scanf("%d%d",&T,&n);
    while(T--){
        memset(bot,0,sizeof(bot));
        flag=0;
        ans=2147483647;
            for(re int i=1;i<=n;i++){
            char c[4];
            scanf("%s",c);
            int num;
            if(strlen(c)==1){
                if(c[0]=='0'){
                    int u;
                    scanf("%d",&u);
                    if(u==1) bot[15]++;
                    else bot[14]++;
                    continue;
                }
                else num=cal1(c[0]);
            }
            else num=cal2(c[0],c[1]);
            bot[num]++;
            scanf("%s",c);
        }
        dfs(0);
        printf("%d\n",ans);
    }
    
    return 0;
}

啊呀,只有三十分

然后发现一个高级优化:对于单牌,我们出牌顺序不影响答案

所以出单牌时只要找到第一个可以出的就可以了

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define re register  
int n;
int s[105];
int bot[105]={0};
int cbo[105];
bool flag;
int start;
int ans=2147483647;
int cal1(char c){
    if(c=='1') return 12;
    if(c=='3') return 1;
    if(c=='4') return 2;
    if(c=='5') return 3;
    if(c=='6') return 4;
    if(c=='7') return 5;
    if(c=='8') return 6;
    if(c=='9') return 7;
    if(c=='2') return 13;
}
int cal2(char a,char b){
    if(a=='0'&&b=='1') return 14;//Big King
    if(a=='0'&&b=='2') return 15;//Small King
    if(a=='1'&&b=='0') return 8;
    if(a=='1'&&b=='1') return 9;
    if(a=='1'&&b=='2') return 10;
    if(a=='1'&&b=='3') return 11;
}
bool check(){
    for(re int i=1;i<=15;i++) if(bot[i]!=0) return 0;
    return 1;
}
int T;
void print(){
    for(re int i=1;i<=15;i++) printf("%d ",bot[i]);
    printf("\n");
}
inline void dfs(int step){
    //print();
//    cout<<step<<endl;
    if(flag==1) return;
    
    if(step>=ans) return;
    if(check()){
        ans=step;
        return;
    }
    for(re int i=n;i>=5;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=13) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<1) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]--;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]++;
        } 
    } 
    for(re int i=n;i>=3;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=13) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<2) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]-=2;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]+=2;
        } 
    } 
    for(re int i=n;i>=2;i--){
        for(re int j=1;j<=15;j++){
            if(i+j-1>=13) continue;
            bool pp=0;
            for(re int k=j;k<=i+j-1;k++) if(bot[k]<3) {pp=1;break;}
            if(pp==1) continue;
            for(re int k=j;k<=i+j-1;k++) bot[k]-=3;
            dfs(step+1);
            for(re int k=j;k<=i+j-1;k++) bot[k]+=3;
        } 
    } 
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<1) continue;
                bot[i]-=4;
                bot[j]--;
                bot[k]--;
                dfs(step+1);
                bot[i]+=4;
                bot[j]++;
                bot[k]++;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<2) continue;
                bot[i]-=4;
                bot[j]-=2;
                bot[k]-=2;
                dfs(step+1);
                bot[i]+=4;
                bot[j]+=2;
                bot[k]+=2;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            bot[i]-=3;
            bot[j]--;
            dfs(step+1);
            bot[i]+=3;
            bot[j]++;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=3;
            bot[j]-=2;
            dfs(step+1);
            bot[i]+=3;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=4;
            bot[j]-=2;
            dfs(step+1);
            bot[i]+=4;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<4) continue;
            bot[i]-=4;
            bot[j]-=4;
            dfs(step+1);
            bot[i]+=4;
            bot[j]+=4;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]>0){
            if(bot[i]>3){
                bot[i]-=4;
                dfs(step+1);
                bot[i]+=4;
            }
            if(bot[i]>2){
                bot[i]-=3;
                dfs(step+1);
                bot[i]+=3;
            }
            if(bot[i]>1){
                bot[i]-=2;
                dfs(step+1);
                bot[i]+=2;
            }
            if(bot[i]>0){
                bot[i]--;
                dfs(step+1);
                bot[i]++;
            }
            break;
        }
    }
    if(bot[14]==1&&bot[15]==1){
        bot[14]--,bot[15]--;
        dfs(step+1);
        bot[14]++,bot[15]++;
    }
}
int ss[100],u=0;
int main(){
    scanf("%d%d",&T,&n);
    for(int pp=1;pp<=T;pp++){
        memset(bot,0,sizeof(bot));
        flag=0;
        ans=2147483647;
            for(re int i=1;i<=n;i++){
            char c[4];
            scanf("%s",c);
            int num;
            if(strlen(c)==1){
                if(c[0]=='0'){
                    int u;
                    scanf("%d",&u);
                    if(u==1) bot[15]++;
                    else bot[14]++;
                    continue;
                }
                else num=cal1(c[0]);
            }
            else num=cal2(c[0],c[1]);
            //if(pp==26) ss[++u]=num;
            bot[num]++;
            scanf("%s",c);
        }
        /*
        if(pp==26){
            for(int i=1;i<=u;i++) printf("%d ",ss[i]);
            printf("\n");
            system("pause");
        }
        */
        //print();
        dfs(0);
        printf("%d\n",ans);
    }
    
    return 0;
}

啊呀,90分

再考虑强剪枝:

现在出不了顺子,以后也出不了

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define re register  
int n;
int s[105];
int bot[105]={0};
int cbo[105];
bool flag;
int start;
int ans=2147483647;
int cal1(char c){
    if(c=='1') return 12;
    if(c=='3') return 1;
    if(c=='4') return 2;
    if(c=='5') return 3;
    if(c=='6') return 4;
    if(c=='7') return 5;
    if(c=='8') return 6;
    if(c=='9') return 7;
    if(c=='2') return 13;
}
int cal2(char a,char b){
    if(a=='0'&&b=='1') return 14;//Big King
    if(a=='0'&&b=='2') return 15;//Small King
    if(a=='1'&&b=='0') return 8;
    if(a=='1'&&b=='1') return 9;
    if(a=='1'&&b=='2') return 10;
    if(a=='1'&&b=='3') return 11;
}
bool check(){
    for(re int i=1;i<=15;i++) if(bot[i]!=0) return 0;
    return 1;
}
int T;
void print(){
    for(re int i=1;i<=15;i++) printf("%d ",bot[i]);
    printf("\n");
}
inline void dfs(int step,bool singly,bool doubly,bool tribly){
    //print();
//    cout<<step<<endl;
    if(flag==1) return;
    
    if(step>=ans) return;
    if(check()){
        ans=step;
        return;
    }
    if(singly){
        bool io=0;
        for(re int i=n;i>=5;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<1) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]--;
                dfs(step+1,singly,doubly,tribly);
                for(re int k=j;k<=i+j-1;k++) bot[k]++;
            } 
        } 
        if(io==0) singly=0;
    }
    if(doubly){
        bool io=0;
        for(re int i=n;i>=3;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<2) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]-=2;
                dfs(step+1,singly,doubly,tribly);
                for(re int k=j;k<=i+j-1;k++) bot[k]+=2;
            } 
        } 
        if(io==0) doubly=0;
    }
    if(tribly){
        bool io=0;
        for(re int i=n;i>=2;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<3) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]-=3;
                dfs(step+1,singly,doubly,tribly);
                for(re int k=j;k<=i+j-1;k++) bot[k]+=3;
            } 
        } 
        if(io==0) tribly=0;
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<1) continue;
                bot[i]-=4;
                bot[j]--;
                bot[k]--;
                dfs(step+1,singly,doubly,tribly);
                bot[i]+=4;
                bot[j]++;
                bot[k]++;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            for(re int k=1;k<=15;k++){
                if(j==k||i==k) continue;
                if(bot[k]<2) continue;
                bot[i]-=4;
                bot[j]-=2;
                bot[k]-=2;
                dfs(step+1,singly,doubly,tribly);
                bot[i]+=4;
                bot[j]+=2;
                bot[k]+=2;
            }
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<1) continue;
            bot[i]-=3;
            bot[j]--;
            dfs(step+1,singly,doubly,tribly);
            bot[i]+=3;
            bot[j]++;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<3) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=3;
            bot[j]-=2;
            dfs(step+1,singly,doubly,tribly);
            bot[i]+=3;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=4;
            bot[j]-=2;
            dfs(step+1,singly,doubly,tribly);
            bot[i]+=4;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<4) continue;
            bot[i]-=4;
            bot[j]-=4;
            dfs(step+1,singly,doubly,tribly);
            bot[i]+=4;
            bot[j]+=4;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]>0){
            if(bot[i]>3){
                bot[i]-=4;
                dfs(step+1,singly,doubly,tribly);
                bot[i]+=4;
            }
            if(bot[i]>2){
                bot[i]-=3;
                dfs(step+1,singly,doubly,tribly);
                bot[i]+=3;
            }
            if(bot[i]>1){
                bot[i]-=2;
                dfs(step+1,singly,doubly,tribly);
                bot[i]+=2;
            }
            if(bot[i]>0){
                bot[i]--;
                dfs(step+1,singly,doubly,tribly);
                bot[i]++;
            }
            break;
        }
    }
    if(bot[14]==1&&bot[15]==1){
        bot[14]--,bot[15]--;
        dfs(step+1,singly,doubly,tribly);
        bot[14]++,bot[15]++;
    }
}
int ss[100],u=0;
int main(){
    scanf("%d%d",&T,&n);
    for(int pp=1;pp<=T;pp++){
        memset(bot,0,sizeof(bot));
        flag=0;
        ans=2147483647;
            for(re int i=1;i<=n;i++){
            char c[4];
            scanf("%s",c);
            int num;
            if(strlen(c)==1){
                if(c[0]=='0'){
                    int u;
                    scanf("%d",&u);
                    if(u==1) bot[15]++;
                    else bot[14]++;
                    continue;
                }
                else num=cal1(c[0]);
            }
            else num=cal2(c[0],c[1]);
            //if(pp==26) ss[++u]=num;
            bot[num]++;
            scanf("%s",c);
        }
        /*
        if(pp==26){
            for(int i=1;i<=u;i++) printf("%d ",ss[i]);
            printf("\n");
            system("pause");
        }
        */
        //print();
        dfs(0,1,1,1);
        printf("%d\n",ans);
    }
    
    return 0;
}

啊呀,95分

考虑出3带1、2,4带2、2对

现在出不了,以后也出不了

代码:

(终于AC)

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ctime>
using namespace std;
#define re register  
int n;
int s[105];
int bot[105]={0};
int cbo[105];
bool flag;
int start;
int ans=2147483647;
int cal1(char c){
    if(c=='1') return 12;
    if(c=='3') return 1;
    if(c=='4') return 2;
    if(c=='5') return 3;
    if(c=='6') return 4;
    if(c=='7') return 5;
    if(c=='8') return 6;
    if(c=='9') return 7;
    if(c=='2') return 13;
}
int cal2(char a,char b){
    if(a=='0'&&b=='1') return 14;//Big King
    if(a=='0'&&b=='2') return 15;//Small King
    if(a=='1'&&b=='0') return 8;
    if(a=='1'&&b=='1') return 9;
    if(a=='1'&&b=='2') return 10;
    if(a=='1'&&b=='3') return 11;
}
bool check(){
    for(re int i=1;i<=15;i++) if(bot[i]!=0) return 0;
    return 1;
}
int T;
void print(){
    for(re int i=1;i<=15;i++) printf("%d ",bot[i]);
    printf("\n");
}
inline void dfs(int step,bool singly,bool doubly,bool tribly,bool threeone,bool threetwo,bool fourtwo,bool fourfour){
    //print();
//    cout<<step<<endl;
    if(flag==1) return;
    
    if(step>=ans) return;
    if(check()){
        ans=step;
        return;
    }
    if(singly){
        bool io=0;
        for(re int i=n;i>=5;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<1) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]--;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                for(re int k=j;k<=i+j-1;k++) bot[k]++;
            } 
        } 
        if(io==0) singly=0;
    }
    if(doubly){
        bool io=0;
        for(re int i=n;i>=3;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<2) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]-=2;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                for(re int k=j;k<=i+j-1;k++) bot[k]+=2;
            } 
        } 
        if(io==0) doubly=0;
    }
    if(tribly){
        bool io=0;
        for(re int i=n;i>=2;i--){
            for(re int j=1;j<=15;j++){
                if(i+j-1>=13) continue;
                bool pp=0;
                for(re int k=j;k<=i+j-1;k++) if(bot[k]<3) {pp=1;break;}
                if(pp==1) continue;
                io=1;
                for(re int k=j;k<=i+j-1;k++) bot[k]-=3;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                for(re int k=j;k<=i+j-1;k++) bot[k]+=3;
            } 
        } 
        if(io==0) tribly=0;
    }
    if(fourtwo){
        bool io=0;
        for(re int i=1;i<=15;i++){
            if(bot[i]<4) continue;
            for(re int j=1;j<=15;j++){
                if(i==j) continue;
                if(bot[j]<1) continue;
                for(re int k=1;k<=15;k++){
                    if(j==k||i==k) continue;
                    if(bot[k]<1) continue;
                    io=1;
                    bot[i]-=4;
                    bot[j]--;
                    bot[k]--;
                    dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                    bot[i]+=4;
                    bot[j]++;
                    bot[k]++;
                }
            }
        }
        if(io==0) fourtwo=0;
    }
    if(fourfour){
        bool io=0;
        for(re int i=1;i<=15;i++){
            if(bot[i]<4) continue;
            for(re int j=1;j<=15;j++){
                if(i==j) continue;
                if(bot[j]<2) continue;
                for(re int k=1;k<=15;k++){
                    if(j==k||i==k) continue;
                    if(bot[k]<2) continue;
                    io=1;
                    bot[i]-=4;
                    bot[j]-=2;
                    bot[k]-=2;
                    dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                    bot[i]+=4;
                    bot[j]+=2;
                    bot[k]+=2;
                }
            }
        }
        if(io==0) fourfour=0;
    }
    if(threeone){
        bool io=0;
        for(re int i=1;i<=15;i++){
            if(bot[i]<3) continue;
            for(re int j=1;j<=15;j++){
                if(i==j) continue;
                if(bot[j]<1) continue;
                io=1;
                bot[i]-=3;
                bot[j]--;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]+=3;
                bot[j]++;
            }
        }
        if(io==0) threeone=0;
    }
    if(threetwo){
        bool io=0;
        for(re int i=1;i<=15;i++){
            if(bot[i]<3) continue;
            for(re int j=1;j<=15;j++){
                if(i==j) continue;
                if(bot[j]<2) continue;
                io=1;
                bot[i]-=3;
                bot[j]-=2;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]+=3;
                bot[j]+=2;
            }
        }
        if(io==0) threetwo=0;
    }
        
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<2) continue;
            bot[i]-=4;
            bot[j]-=2;
            dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
            bot[i]+=4;
            bot[j]+=2;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]<4) continue;
        for(re int j=1;j<=15;j++){
            if(i==j) continue;
            if(bot[j]<4) continue;
            bot[i]-=4;
            bot[j]-=4;
            dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
            bot[i]+=4;
            bot[j]+=4;
        }
    }
    for(re int i=1;i<=15;i++){
        if(bot[i]>0){
            if(bot[i]>3){
                bot[i]-=4;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]+=4;
            }
            if(bot[i]>2){
                bot[i]-=3;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]+=3;
            }
            if(bot[i]>1){
                bot[i]-=2;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]+=2;
            }
            if(bot[i]>0){
                bot[i]--;
                dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
                bot[i]++;
            }
            break;
        }
    }
    if(bot[14]==1&&bot[15]==1){
        bot[14]--,bot[15]--;
        dfs(step+1,singly,doubly,tribly,threeone,threetwo,fourtwo,fourfour);
        bot[14]++,bot[15]++;
    }
}
int ss[100],u=0;
int main(){
    scanf("%d%d",&T,&n);
    for(int pp=1;pp<=T;pp++){
        memset(bot,0,sizeof(bot));
        flag=0;
        ans=2147483647;
            for(re int i=1;i<=n;i++){
            char c[4];
            scanf("%s",c);
            int num;
            if(strlen(c)==1){
                if(c[0]=='0'){
                    int u;
                    scanf("%d",&u);
                    if(u==1) bot[15]++;
                    else bot[14]++;
                    continue;
                }
                else num=cal1(c[0]);
            }
            else num=cal2(c[0],c[1]);
            //if(pp==26) ss[++u]=num;
            bot[num]++;
            scanf("%s",c);
        }
        /*
        if(pp==26){
            for(int i=1;i<=u;i++) printf("%d ",ss[i]);
            printf("\n");
            system("pause");
        }
        */
        //print();
        dfs(0,1,1,1,1,1,1,1);
        printf("%d\n",ans);
    }
    
    return 0;
}

 

posted @ 2019-11-10 21:25  QYJ060604  阅读(147)  评论(0编辑  收藏  举报