DFS搜索顺序

马走日

询问马走完全局有多少可行方案,那么也就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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值