面试笔试算法:深搜

由数字 0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 1 构成,围圈时只走上下左右 4 个方向。现要求把闭合圈内的所有空间都填写成 2。例如:6×6 的方阵 (n=6),涂色前和涂色后的方阵如下:

#include <iostream>
using namespace std;

//预留出一圈,并将外圈连通的区域标记为2,那么剩下的为0区域则是要求区域
int n;
int mmap[100][100];
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};

void func(int x, int y){
	for (int i = 0; i < 4; i++){
		int xx = x + dir[i][0];
		int yy = y + dir[i][1];
		if (xx >= 0 && xx <= n + 1 && yy >= 0 && yy <= n + 1 && mmap[xx][yy] == 0){//判断边界
			mmap[xx][yy] = 2;//标记为新数字
			func(xx, yy);//下一轮
		}
	}
}

int main(){
	cin >> n;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= n; j++){
			cin >> mmap[i][j];
		}
	}
	mmap[0][0] = 2;
	func(0, 0);
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= n; j++){
			(j != 1) && (cout << " ");
			if (mmap[i][j] == 2) cout << 0;
			if (mmap[i][j] == 1) cout << 1;
			if (mmap[i][j] == 0) cout << 2;
		}
		cout << endl;
	}

}

​ 有一个仅由数字 0 与 1 组成的 n×m 格迷宫。若你位于一格 0 上,那么你可以移动到相邻 4 格中的某一格 1 上,同样若你位于一格 1 上,那么你可以移动到相邻 4 格中的某一格 0

上。

​ 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

#include <iostream>
using namespace std;

int m, n, sx, sy, ans;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
char mmap[3005][3005];//
int mark[3005][3005];//记录有没有走过

void func(int x, int y){
	for (int i = 0; i < 4; i++){
		int xx = x + dir[i][0];
		int yy = y + dir[i][1];
		//cout << "hi"<<xx << yy << endl;
		//printf("mark[xx][yy] = %d\n", mark[xx][yy]);
		//printf("mmap[xx][yy] = %d\n", mmap[xx][yy]);
		if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && mark[xx][yy] == 0 && mmap[xx][yy] != mmap[x][y]){
			//printf("xx, yy = %c, %c", xx, yy);
			ans++;
			mark[xx][yy] = 1;
			func(xx, yy);
		}
	}
}


int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i++){//输入是从1开始
		cin >> &mmap[i][1];
	}
	cin >> sx >> sy;
	ans = 1;
	mark[sx][sy] = 1;
	func(sx, sy);
	cout << ans << endl;
	return 0;
	
}

​ 有一个仅由数字 0 与 1 组成的 n×m 格迷宫。若你位于一格 0 上,那么你可以移动到相邻 4 格中的某一格 1 上,同样若你位于一格 1 上,那么你可以移动到相邻 4 格中的某一格 0

上。

​ 你的任务是:对于给定的迷宫,询问 k
次从某一格开始能移动到多少个格子(包含自身)。

#include <iostream>
#include <queue>
using namespace std;

int m, n, k, sx, sy, ans;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
char mmap[3005][3005];
int mark[3005][3005];//记录有没有走过

struct node{
	int x, y;
};

queue<node> que;

void check(){
	while(!que.empty()){
		node t = que.front();
		que.pop();
		mark[t.x][t.y] = ans;
	}
}

	
void func(int x, int y){
	//一个连通区的压入一个队列
	que.push((node){x, y});
	for (int i = 0; i < 4; i++){
		int xx = x + dir[i][0];
		int yy = y + dir[i][1];
		//cout << xx << " " << yy << endl;
		//cout << "mark[xx][yy]=" << mark[xx][yy]<< endl;
		if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && mark[xx][yy] == 0 && mmap[xx][yy] != mmap[x][y]){
			ans++;
			mark[xx][yy] = 1;//走过一遍不用再走第二遍,不连通肯定就不连通了
			func(xx, yy);
		}
	}
}


int main(){
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++){//输入是从1开始
		cin >> &mmap[i][1];
	}
	for (int i = 1; i <=n; i ++){
		for (int j = 1; j <=m; j++){
			if (mark[i][j] == 0){//走过就不用走了
				ans = 1;
				mark[i][j] = 1;
				//cout << "func(i, j)" << i << j << endl;
				func(i, j);
				check();//将连通区域(队列)值设为联通数目		
			}

		}
	}
	for (int i = 0; i < k; i++){
		int a, b;
		cin >> a >> b;
		cout << mark[a][b] << endl;
	}
	
	return 0;
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值