题意:给你十三章麻将,问可以糊哪些牌?
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
int tile[40];
int ret[40], retCnt;
bool ChiiToitsu()
{
int cnt = 0;
for(int i = 1; i <= 37; i++)
{
if(tile[i] % 2 == 1) return false;
if(tile[i] == 2) cnt++;
}
if(cnt == 7) return true;
return false;
}
bool KokushiMuso()
{
int cnt = 0;
bool eye = false;
for(int i = 0; i <= 20; i += 10)
{
if(tile[1+i] >= 1) cnt++;
if(tile[1+i] >= 2) eye = true;
if(tile[9+i] >= 1) cnt++;
if(tile[9+i] >= 2) eye = true;
}
for(int i = 31; i <= 37; i++)
{
if(tile[i] >= 1) cnt++;
if(tile[i] >= 2) eye = true;
}
if(eye && cnt == 13) return true;
return false;
}
bool check3X4(int eye)
{
int tmp[40], i, j;
memcpy(tmp, tile, sizeof(tmp));
tmp[eye] -= 2;
for(i = 31; i <= 37; i++)
if(!(tmp[i] == 0 || tmp[i] == 3))
return false;
for(i = 1, j = 0; i <= 4; i++)
{
while(j <= 37 && tmp[j] == 0) j++;
if(j == 37) break;
if(tmp[j] >= 3)
tmp[j] -= 3;
else
{
if(tmp[j+1] > 0 && tmp[j+2] > 0) { tmp[j]--; tmp[j+1]--; tmp[j+2]--;}
else return false;
}
}
return true;
}
bool win()
{
if(ChiiToitsu()) return true;
if(KokushiMuso()) return true;
for(int i = 1; i <= 37; i++) //枚举eye
if(tile[i] >= 2 && check3X4(i)) //当tile[i]>=2,尝试以i为eye
return true;
return false;
}
int main()
{
int t, i;
char s[3];
scanf("%d",&t);
while(t--)
{
memset(tile, 0, sizeof(tile));
for(i = 1; i <= 13; i++)
{
scanf("%s",s);
if(s[1] == 'm') tile[s[0]-'0']++;
else if(s[1] == 's') tile[s[0]-'0'+10]++;
else if(s[1] == 'p') tile[s[0]-'0'+20]++;
else tile[s[0]-'0'+30]++;
}
retCnt = 0;
for(i = 1; i <= 37; i++)
if(i != 10 && i != 20 && i != 30 && tile[i] < 4)
{
tile[i]++;
if(win()) ret[retCnt++] = i;
tile[i]--;
}
if(retCnt == 0)
{
printf("Nooten\n");
continue;
}
printf("%d",retCnt);
for(i = 0; i < retCnt; i++)
{
printf(" %d",ret[i] % 10);
if(ret[i] < 10) printf("m");
else if(ret[i] > 10 && ret[i] < 20) printf("s");
else if(ret[i] > 20 && ret[i] < 30) printf("p");
else if(ret[i] > 30 && ret[i] <= 37) printf("c");
}
printf("\n");
}
return 0;
}