A boy named Vasya wants to play an old Russian solitaire called "Accordion". In this solitaire, the player must observe the following rules:
Vasya has already shuffled the cards and put them on the table, help him understand whether completing this solitaire is possible or not.
The first input line contains a single integer n (1 ≤ n ≤ 52) — the number of cards in Vasya's deck. The next line contains n space-separated strings c1, c2, ..., cn, where string ci describes the i-th card on the table. Each string ci consists of exactly two characters, the first one represents the card's value, the second one represents its suit. Cards on the table are numbered from left to right.
A card's value is specified by one of these characters: "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A". A card's suit is specified by one of these characters: "S", "D", "H", "C".
It is not guaranteed that the deck has all possible cards. Also, the cards in Vasya's deck can repeat.
On a single line print the answer to the problem: string "YES" (without the quotes) if completing the solitaire is possible, string "NO" (without the quotes) otherwise.
4 2S 2S 2C 2C
YES
2 3S 2C
NO
In the first sample you can act like that:
In the second sample there is no way to complete the solitaire.
题意:第一行输入n,代表有n张牌(1,2,3,4,...,n)
每张牌是由连个字符表示,数字代表牌号,字符代表花号,如果n 和 n-3的花号或者牌号一样,就可以合并成同一张,合成的新牌是n,同理n和n-1,这两张牌也满足这种情况,问最后能否合成一堆牌,能就输出YES,否则就输出NO。
比如第一组样例,4和1合并成2C,然后3和2合并成2C,最后1和2再合并成一堆牌,而第二组样例中,1和2的牌号和花号都不一样,所以不能合并。
典型的记忆化搜索,处理好牌与牌之间的关系就好做了。
#include <stdio.h>
#include <string.h>
char c[53][3];
int M[53][53];
bool vis[53][53][53][53];
bool dfs(int m, int m1, int m2, int m3) {
//标记表示已经有过这种状态
if(vis[m][m1][m2][m3]) return false;
//当剩下四张牌时
if(m == 3 && M[m1][m3] && M[m3][m2]) return true;
//当剩下五张牌时
if(M[m2][m3] && dfs(m-1, m-4, m1, m3)) return true;
//当大于等于五张牌时
if(m >= 4 && M[m3][m-4] && dfs(m-1, m3, m1, m2)) return true;
//状态标记
vis[m][m1][m2][m3] = 1;
return false;
}
int main() {
int n;
while(~scanf("%d",&n)) {
for(int i = 0; i < n; i++) {
scanf("%s",c[i]);
}
if(n == 1) {
printf("YES\n");
continue;
}
memset(M, 0, sizeof(M));
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(i != j)
if(c[i][0] == c[j][0] || c[i][1] == c[j][1]) {
M[i][j] = 1;
M[j][i] = 1;
}
}
}
if(dfs(n, n-3, n-2, n-1)) puts("YES");
else puts("NO");
}
return 0;
}