题意:给出十三章牌,问有几种赢的方法。
思路: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; }