扫地机器人(dfs基础)

题面

Mike同学在为扫地机器人设计一个在矩形区域中行走的算法,Mike是这样设计的:先把机器人放在出发点 (1,1)(1,1) 点上,机器人在每个点上都会沿用如下的规则来判断下一个该去的点是哪里。规则:优先向右,如果向右不能走(比如:右侧出了矩形或者右侧扫过了)则尝试向下,向下不能走则尝试向左,向左不能走则尝试向上;直到所有的点都扫过。

Mike为了验证自己设计的算法是否正确,打算先模拟一下这个算法,每当机器人走过一个单元格时,会在单元格内标记一个数字,这个数字从 11 开始,每经过一个单元格数字会递增 11 ,直到所有的单元格都扫一遍,也就是所有的单元格都标记过数字,机器人会自动停止。

请你帮助Mike设计一个程序,按照上面的规则,将一个 n×m 大小的矩形,标记一下数字,输出最终标记的结果。

输入:

一行内有 22 个两个整数 n 和 m ,用空格隔开,分别代表矩形区域的行数(高)和列数(宽)。

1<n,m<10。

输出:

输出按题意机器人走过每个点之后,标记数字的结果,每个数字输出时场宽设置为 3。

链接:Link. 

 最基础的dfs题,根据题目右,下,左,上得顺序递归即可(要注意不能出边界和不重复走)

解法1:递归前暴力判断

#include <bits/stdc++.h>
using namespace std;
int n , m;
int a[20][20];
void dfs(int x , int y , int k){
	a[x][y] = k;
	if (y + 1 <= m && a[x][y+1] == 0 )
		dfs(x , y + 1 , k + 1);
	if (x + 1 <= n && a[x+1][y] == 0 )
		dfs(x + 1 , y  , k + 1);
	if (y - 1 >= 1 && a[x][y-1] == 0 )
		dfs(x , y - 1 , k + 1);
	if (x - 1 >= 1 && a[x-1][y] == 0 )
		dfs(x - 1 , y , k + 1);
}

int main(){
	scanf("%d%d" , &n , &m);
	dfs(1,1,1);
	for ( int i = 1 ; i <= n ; i++ ){
		for ( int j= 1 ; j <= m ; j++ )
			cout << setw(3) << a[i][j];
		printf("\n");
	}
	return 0;
}

解法2:在递归前先大判断再暴力尝试

#include <bits/stdc++.h>
using namespace std;
int n , m;
int a[20][20];
void dfs(int x , int y , int k){
	if(x >= 1 && x <= n && y >= 1 && y <= m && a[x][y] == 0 ){
		a[x][y] = k;
		dfs(x , y + 1  , k + 1);
	
		dfs(x + 1 , y  , k + 1);
	
		dfs(x , y - 1  , k + 1);

		dfs(x - 1 , y  , k + 1);
	}
	
}
  
int main(){
	scanf("%d%d" , &n , &m);
	dfs(1,1,1);
	for ( int i = 1 ; i <= n ; i++ ){
		for ( int j= 1 ; j <= m ; j++ )
			cout << setw(3) << a[i][j];
		printf("\n");
	}
	return 0;
}

 解法3:在递归前先大判断再用方向数组+循环尝试

#include <bits/stdc++.h>
using namespace std;
int n , m;
int a[20][20];
int fx[5] = {0 , 0 , 1 , 0 , -1} , fy[5] = {0 , 1 , 0 , -1 , 0};
void dfs(int x , int y , int k){
	if(x >= 1 && x <= n && y >= 1 && y <= m && a[x][y] == 0 ){
		a[x][y] = k;
		int tx , ty;
		for ( int i = 1 ; i <= 4 ; i++ ){
			tx = x + fx[i];
			ty = y + fy[i];
			dfs(tx , ty , k+1);
		}
	}
	
}
  
int main(){
	scanf("%d%d" , &n , &m);
	dfs(1,1,1);
	for ( int i = 1 ; i <= n ; i++ ){
		for ( int j= 1 ; j <= m ; j++ )
			cout << setw(3) << a[i][j];
		printf("\n");
	}
	return 0;
}

 解法4:用方向数组+循环尝试 (在每次递归前判断决定是否递归)

#include <bits/stdc++.h>
using namespace std;
int n , m;
int a[20][20];
int fx[5] = {0 , 0 , 1 , 0 , -1} , fy[5] = {0 , 1 , 0 , -1 , 0};
void dfs(int x , int y , int k){

	a[x][y] = k;
	int tx , ty;
	for ( int i = 1 ; i <= 4 ; i++ ){
		tx = x + fx[i];
		ty = y + fy[i];			
		if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == 0 )
			dfs(tx , ty , k+1); 
	}
	
}
  
int main(){
	scanf("%d%d" , &n , &m);
	dfs(1,1,1);
	for ( int i = 1 ; i <= n ; i++ ){
		for ( int j= 1 ; j <= m ; j++ )
			cout << setw(3) << a[i][j];
		printf("\n");
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值