题意:给出十三章牌,问有几种赢的方法。
思路:DFS枚举所有的情况,记得剪枝。
自己想得几组数据。
7
1s 1s 2s 2s 3s 3s 4s 4s 5s 5s 6s 6s 7s
3 1s 4s 7s
1s 1s 3s 3s 5s 5s 1p 1p 5m 5m 7c 7c 1c
1 1c
1s 2s 3s 2c 2c 2c 2p 3p 5m 6m 7m 1p 1p
2 1p 4p
1p 1p 2p 3p 4s 5s 6s 7c 7c 3s 3s 2m 2m
Nooten
1s 2s 3s 4s 5s 6s 7s 8s 9s 9s 9s 2c 3c
Nooten
1s 2s 3s 4s 5s 6s 7s 8s 9s 9s 9s 2c 2c
4 3s 6s 9s 2c
1s 9s 1m 9m 1p 9p 1c 2c 3c 4c 5c 6c 7c
13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <stack>
#define LL long long
#define EPS (1e-8)
#define Left true
#define Right false
using namespace std;
struct N
{
int id,ty;
}s[15];
struct E
{
int id;
char ty;
}st[100000];
int mark[5][10];
bool dfs_con;
bool dfs(int t1,int t2,int eye,int r,int c)
{
int i,j;
if(dfs_con)
return true;
for(i = 1;i <= r; ++i)
{
for(j = 1;j < (i == r ? c : 9) ; ++j)
{
if(mark[i][j] != 0)
return false;
}
}
if(eye == 1 && mark[r][c] != 3 && mark[r][c] != 0 && ( (c == 9 && mark[r][c-1] == 0) || (c == 1 && mark[r][c+1] == 0) || (1 < c && c < 9 && mark[r][c+1] == 0 && mark[r][c-1] == 0)))
{
return false;
}
if(eye == 0 && mark[r][c] == 4 && mark[r][c] == 1 && ( (c == 9 && mark[r][c-1] == 0) || (c == 1 && mark[r][c+1] == 0) || (1 < c && c < 9 && mark[r][c+1] == 0 && mark[r][c-1] == 0)))
{
return false;
}
if(t1+t2 == 4 && eye)
{
dfs_con = true;
return true;
}
for(i = r;i <= 4; ++i)
{
for(j = (i == r ? c : 1) ; j <= 9; ++j)
{
if(eye == 0)
{
if(mark[i][j] >= 2)
{
mark[i][j] -= 2;
if(dfs(t1,t2,1,i,j) == true)
return true;
mark[i][j] += 2;
}
}
if(mark[i][j] >= 3)
{
mark[i][j] -= 3;
if(dfs(t1+1,t2,eye,i,j) == true)
{
return true;
}
mark[i][j] += 3;
}
if(i != 4 && j <= 7 && mark[i][j] >= 1 && mark[i][j+1] >= 1 && mark[i][j+2] >= 1)
{
mark[i][j]--;
mark[i][j+1]--;
mark[i][j+2]--;
if(dfs(t1,t2+1,eye,i,j) == true)
{
return true;
}
mark[i][j]++;
mark[i][j+1]++;
mark[i][j+2]++;
}
}
}
return false;
}
bool Is_Win(N *p)
{
int eye;
int i,j;
memset(mark,0,sizeof(mark));
for(i = 1;i <= 14; ++i)
{
mark[p[i].ty][p[i].id]++;
}
eye = 0;
for(i = 1;i <= 4; ++i)
{
for(j = 1;j <= 9; ++j)
{
if(mark[i][j] == 2)
{
eye++;
}
if(mark[i][j] >= 5)
return false;
}
}
if(eye == 7)
{
return true;
}
for(i = 1;i <= 3 && 1 <= mark[i][1] && 1 <= mark[i][9] ; ++i)
;
if(i == 4)
{
for(i = 1;i <= 7 && 1 <= mark[4][i] ; ++i)
;
if(i == 8)
{
for(i = 1;i <= 3 ; ++i)
{
if(2 == mark[i][1] || 2 == mark[i][9])
return true;
}
for(i = 1;i <= 7; ++i)
{
if(mark[4][i] == 2)
return true;
}
}
}
dfs_con = false;
return dfs(0,0,0,1,1);
}
int main()
{
int n,i;
int top;
scanf("%d",&n);
char c;
while(n--)
{
top = 0;
E temp;
for(i = 1;i <= 13; ++i)
{
scanf("%d%c",&s[i].id,&c);
if(c == 'm')
{
s[i].ty = 1;
}
else if(c == 's')
{
s[i].ty = 2;
}
else if(c == 'p')
{
s[i].ty = 3;
}
else if(c == 'c')
{
s[i].ty = 4;
}
}
for(i = 1;i <= 9; ++i)
{
s[14].id = i;
s[14].ty = 1;
if(Is_Win(s))
{
temp.id = i;
temp.ty = 'm';
st[top++] = temp;
}
}
for(i = 1;i <= 9; ++i)
{
s[14].id = i;
s[14].ty = 2;
if(Is_Win(s))
{
temp.id = i;
temp.ty = 's';
st[top++] = temp;
}
}
for(i = 1;i <= 9; ++i)
{
s[14].id = i;
s[14].ty = 3;
if(Is_Win(s))
{
temp.id = i;
temp.ty = 'p';
st[top++] = temp;
}
}
for(i = 1;i <= 7; ++i)
{
s[14].id = i;
s[14].ty = 4;
if(Is_Win(s))
{
temp.id = i;
temp.ty = 'c';
st[top++] = temp;
}
}
if(top == 0)
{
printf("Nooten\n");
}
else
{
printf("%d",top);
for(i = 0;i < top; ++i)
{
printf(" %d%c",st[i].id,st[i].ty);
}
printf("\n");
}
}
return 0;
}