题意:
给你n堆扑克,每次从后往前,最后一堆扑克可以放在它前面一堆或者前面三堆的花色一样或者数字一样的那堆扑克上面,问最后能否把扑克都变为一堆。
思路:
状态记忆化搜索,即深搜过程中,不断记录不能成功的扑克状态,当再次搜索到此状态时,不往下搜索。时间复杂度感觉不知道怎么算。。。。
#include<iostream>
#include<string>
#include<map>
using namespace std;
const int MAX=55;
int n;
bool flag;
string a[MAX];
map<string,bool> vis;
void DFS(int i){
if(i==1){
flag=true;
return;
}
if(i-1>=1&&(a[i][0]==a[i-1][0]||a[i][1]==a[i-1][1])){
//变换
string tmp;
tmp=a[i-1];
a[i-1]=a[i];
//判断前半段是否合法
string pre;
for(int j=1;j<=i-1;j++){
pre+=a[j];
}
if(vis[pre]!=true){
vis[pre]=true;
DFS(i-1);
}
if(flag) return;
a[i-1]=tmp;
}
if(i-3>=1&&(a[i][0]==a[i-3][0]||a[i][1]==a[i-3][1])){
//变换
string tmp;
tmp=a[i-3];
a[i-3]=a[i];
//判断前半段是否合法
string pre;
for(int j=1;j<=i-1;j++){
pre+=a[j];
}
if(vis[pre]!=true){
vis[pre]=true;
DFS(i-1);
}
if(flag) return;
a[i-3]=tmp;
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
flag=false;
DFS(n);
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}