第十五届蓝桥杯模拟赛(第二期)第9题

问题:

小蓝站在一个n行m列的方格图中间,方格图的每一个方格上都标有一个正整数。
如果两个相邻方格(上下左右四个方向相邻)内的数的最大公约数大于1,则可以从其中一个方格移动到另一个方格,当然也可以从另一个方格移回第一个方格。
假设小蓝开始时站在第r行第c列,请问小蓝可以移动到方格图内的多少个方格?

3 6 5 5
2 4 3 4
7 8 3 8

输入示例:

3 4
3 6 5 5
2 4 3 4
7 8 3 8
2 1

输出示例:

5

代码:

#include
#include
using namespace std;
int v[100][100]={0};//标志数组,用来记录坐标是否被访问过
int arr[100][100];
void dfs(int x,int y);
bool zhanzhuan(int x,int y);
bool jieshu(int x,int y);
int n;//方格的行数
int m;//方格的列数 
int co=0;
int main(){
	cout<< "请输入方格的行数和列数:"<<endl;
	cin>>n>>m;
	cout<<"请输入方格中的数字:"<<endl;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>arr[i][j];
		}
	}
	cout<<"请输入起始方格的坐标:"<<endl;
	int x,y;
	cin>>x>>y;
	dfs(x,y);
	cout<< "可移动的位置有:" << co << "个" <<endl;
} 
void dfs(int x,int y){
	if(!jieshu(x,y)){
		return ;
	}
	
	// 向上移动
	if(zhanzhuan(arr[x][y],arr[x-1][y])&&v[x-1][y]==0&&x>=1){
		v[x-1][y]=1;
		co+=1;
		dfs(x-1,y);
		v[x-1][y]=0;
	}
	
	// 向右移动
	if(zhanzhuan(arr[x][y],arr[x][y+1])&&v[x][y+1]==0&&y<=m-2){
		v[x][y+1]=1;
		co+=1;
		dfs(x,y+1);
		v[x][y+1]=0;
	}
	
	// 向下移动
		if(zhanzhuan(arr[x][y],arr[x+1][y])&&v[x+1][y]==0&&x<=n-2){
		v[x+1][y]=1;
		co+=1;
		dfs(x+1,y);
		v[x+1][y]=0;
	}
	
	// 向左移动
	if(zhanzhuan(arr[x][y],arr[x][y-1])&&v[x][y-1]==0&&y>=1){
		v[x][y-1]=1;
		co+=1;
		dfs(x,y-1);
		v[x][y-1]=0;
	}
		
}
bool zhanzhuan(int x,int y){
	int max = x>y?x:y;
	int min = x<y?x:y;
	if(min==0){
		return false;
	}
	int yu=max%min;
	while(yu!=0){
		max=min;
		min=yu;
		yu=max%min;
	}
	if(min>1){
		return true;
	}else{
		return false;
	}
}
bool jieshu(int x,int y){
	int c=0;
	if(zhanzhuan(arr[x][y],arr[x][y+1])){
		c++;
	}
	if(zhanzhuan(arr[x][y],arr[x][y-1])){
		c++;
	}
	if(zhanzhuan(arr[x][y],arr[x+1][y])){
		c++;
	}
	if(zhanzhuan(arr[x][y],arr[x-1][y])){
		c++;
	}
	if(c>0){
		return true;
	}else{
		return false;
	}
}

利用dfs深度搜索,找到每一个符合要求的数组坐标,然后将该数组的下标标识为已访问,记为1,没有访问设为0;

需要注意的是回溯结束的条件,什么时候才能够回溯,就是当前位置的上、下、左、右的位置上的数字都不满足要求,这时候才能回溯

你可能感兴趣的:(蓝桥杯,深度优先,算法)