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;
}