询问马走完全局有多少可行方案,那么也就dfs搜索形成的搜索树有多少分支可行。
那么搜索终点判断条件是什么呢?
我们可以记录一个cnt变量表示已经遍历了点的个数,如果cnt==n*m那么表示所有点都已经遍历过了可以结束遍历
是否需要回溯?
因为我每个分支判断完我仍然需要继续判断下一个分支所以需要回溯
#include <bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f
using namespace std;
typedef pair<int,string> PII;
const int N=1e2+10;
int n,m,ans;
int sx,sy;
int dx[8]= {-2,-2,-1,1,2,2,1,-1},dy[8]= {-1,1,2,2,1,-1,-2,-2};
char M[N][N];
int vis[N][N];
bool flag;
void dfs(int x,int y,int cnt) {
if(cnt==n*m) {//注意这里是判断当前分支是否可行
ans++;
return ;
}
for(int i=0; i<8; i++) {
int nx=x+dx[i],ny=y+dy[i];
if(nx<0||ny<0||nx>=n||ny>=m)continue;
if(!vis[nx][ny]){
vis[nx][ny]=1;
dfs(nx,ny,cnt+1);
vis[nx][ny]=0; //要回溯
}
}
}
int main() {
int T;
cin>>T;
while(T--) {
cin>>n>>m;
cin>>sx>>sy;
memset(vis,0,sizeof(vis));
ans=0;
vis[sx][sy]=1;
dfs(sx,sy,1);
cout<<ans<<endl;
}
return 0;
}
字符串常用函数
利用一个g二维数组预处理一下两个字符串之间能否拼接
#include <bits/stdc++.h>
#define ll long long
#define INF 0x7f7f7f7f
using namespace std;
typedef pair<int,string> PII;
const int N=1e2+10;
int n,m,ans;
int vis[N];
string M[N];
int g[N][N];
void dfs(string str,int k) {
ans=max((int)str.size(),ans);//记录答案
for(int i=0; i<n; i++) {
if(vis[i]==2)continue;//最多使用两次
if(g[k][i]) {
vis[i]+=1;
dfs(str+M[i].substr(g[k][i]),i);
vis[i]-=1;//回溯 求出所有搜索顺序
}
}
}
int main() {
cin>>n;
for(int i=0; i<n; i++) {
cin>>M[i];
}
char st;
cin>>st;
for(int i=0; i<n; i++) { //预处理每个字符串两两之间能否拼凑,拼凑的长度为多少
for(int j=0; j<n; j++) {
string a=M[i],b=M[j];
for(int k=1; k<min(a.size(),b.size()); k++) {
if(a.substr(a.size()-k,k)==b.substr(0,k)) {
g[i][j]=k;
break;
}
}
}
}
for(int i=0; i<n; i++) {
if(M[i][0]==st){
vis[i]+=1;
dfs(M[i],i);
vis[i]-=1;
}
}
cout<<ans;
return 0;
}