这是我职业生涯的最后一题了。acm留给我的太多太多... 别了。
基本的就是用枚举+贪心。
但是有几个小问题:
1.七小对是七个不同的对子。
2.东西南北.. 等不能作为顺子。
考虑这两点,基本上就没有trick了。
#include<iostream>
using namespace std;int cnt[35];
int maso[14]={0,8,9,17,18,26,27,28,29,30,31,32,33};int f( char c )
{if( c>='1' && c<='9' ) return c-'1';if( c=='m' ) return 0;if( c=='s' ) return 9;if( c=='p' ) return 18;return 27;
}char mspc( int x )
{if( x==0 ) return 'm';if( x==1 ) return 's';if( x==2 ) return 'p';return 'c';
}bool judge4x3()
{int i,j,ret=0; int tem[34];for( i=0;i<34;i++ ) tem[i]=cnt[i];for( i=0;i<=18;i+=9 )for( j=0;j<9;j++ ){if( tem[i+j]>=3 )tem[i+j]-=3,ret++;while( j+2<9 && tem[i+j]&& tem[i+j+1]&& tem[i+j+2] )tem[i+j]--,tem[i+j+1]--,tem[i+j+2]--,ret++;}i=27;for( j=0;j<7;j++ ){if( tem[i+j]>=3 )tem[i+j]-=3,ret++;}return ret==4?true:false;
}bool judge1()
{for( int i=0;i<34;i++ ){if( cnt[i]>=2 ){cnt[i]-=2;if( judge4x3() ){cnt[i]+=2;return true;}cnt[i]+=2;}}return false;
}bool judge2()//judge Chii Toitsu
{for( int i=0;i<34;i++ )if( cnt[i]!=2 && cnt[i]!=0 )return false;return true;
}bool judge3()
{for( int i=0;i<7;i++ )if( cnt[i+27]==0 )return false;for( int i=0;i<=18;i+=9 ){if( cnt[i]==0 || cnt[i+8]==0 )return false;for( int j=1;j<8;j++ )if( cnt[i+j] )return false;}return true;
}bool judge()
{if( judge1() ) return true;if( judge2() ) return true;if( judge3() ) return true;return false;
}int main()
{//freopen( "A.in","r",stdin );//freopen( "A.out","w",stdout );int T;scanf( "%d",&T );while( T-- ){char com[11];int rec[34],tot=0;memset( cnt,0,sizeof(cnt) );for( int i=0;i<13;i++ ){scanf("%s",com);cnt[f(com[0])+f(com[1])]++;}for( int i=0;i<34;i++ ){cnt[i]++;if( cnt[i]<=4 && judge() )rec[tot++]=i;cnt[i]--;}if( tot==0 )printf( "Nooten" );else{printf( "%d",tot );for( int i=0;i<tot;i++ )printf( " %d%c",rec[i]%9+1,mspc(rec[i]/9) );}printf( "\n" );}return 0;
}