KUANGBIN专题一简单搜索

棋盘问题

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char mp[12][12];
int n, k, ans, b[12], m;

void dfs(int x) 
{
	if(m == k) {
		ans++;
		return ;
	}
	if(x >= n) return ;
	for(int i = 0; i < n; i++) {
		if(mp[x][i] == '#' && b[i] == 0) {   //符合条件可以下棋
			b[i] = 1;    // 选择下
			m++;
			dfs(x + 1);
			b[i] = 0;   // 选择不下
			m--;
		}
	}
	dfs(x + 1);
}

int main()
{
	while(~scanf("%d %d", &n, &k)) {
		if(n == -1 && k == -1) break;
		memset(b, 0, sizeof(b));
		ans = 0;
		m = 0;
		for(int i = 0; i < n; i++) scanf("%s", mp[i]);
		dfs(0);
		printf("%d
", ans);
	}
	return 0;
}

文章 和这种数字求和问题也是一样的dfs查找。

B - Dungeon Master

三维数组跟平面一样。

dr[4][2] 变成了 dr[6][3], 一样查找一样插入就行

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
char mp[50][50][50];
int vis[50][50][50];
int dr[6][3] = {1,0,0, 0,1,0, 0,0,1, -1,0,0, 0,-1,0, 0,0,-1};
int bfs();
int x, y, z, sx, sy,sz, ex, ey, ez;

struct node {
	int x, y, z;
	int val;
}st, ed;

int main() {
	while(~scanf("%d%d%d", &z, &x, &y)) {
		memset(vis, 0, sizeof(vis));
		if(z == 0 && x == 0 && y == 0) return 0;
		for(int i = 0; i < z; i++) {
			for(int j = 0; j < x; j++) scanf(" %s", mp[i][j]);
			getchar();
		}
		for(int i = 0; i < z; i++) 
			for(int j = 0; j < x; j++) 
				for(int k = 0; k < y; k++) {
					if(mp[i][j][k] == 'S') sz = i, sx = j, sy = k;
					if(mp[i][j][k] == 'E') ez = i, ex = j, ey = k;
				}

		int ans = bfs();
		if(ans != -1) printf("Escaped in %d minute(s).
", ans);
		else printf("Trapped!
");
	}
	return 0;
}

int bfs() {
	queue<node> q;
	st.z = sz, st.x = sx, st.y = sy, st.val = 0;
	vis[st.z][st.x][st.y] = 1;
	q.push(st);
	while(!q.empty()) {
		st = q.front();
		q.pop();
		if(st.z == ez && st.x == ex && st.y == ey) return st.val;
		for(int i = 0; i < 6; i++) {
				ed.z = st.z + dr[i][0];
				ed.x = st.x + dr[i][1];
				ed.y = st.y + dr[i][2];
				if(ed.z>=0&&ed.z<z&&ed.x>=0&&ed.x<x&&ed.y>=0&&ed.y<y&&vis[ed.z][ed.x][ed.y]==0 && (mp[ed.z][ed.x][ed.y]=='.' || mp[ed.z][ed.x][ed.y]=='E')) {
					ed.val = st.val + 1;
					vis[ed.z][ed.x][ed.y] = 1;
					q.push(ed);
				}
				else continue;
		}
	}
	return -1;
}

C - Catch That Cow

题意就是给个n如何变成K,有三种选择+1、-1、*2。 输出最小的变换数。使用bfs。

注意:n k 均小于1e5。 数组一般开MaxN = 1e5 。 但是在 *2 处理时会超过1e5 的数组。所以会报错成Runtime Error。

所以数组开成了2e5 并且还判断了一下 val <= 2 * k。

不过第一次RE后一直在想队列需不需要清空。可能题目不是多组输入。所以没有改也直接过了。

(这个代码写得有点丑,bfs没有单独写出来)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int MaxN = 2e5 + 5;
int vis[MaxN];

struct node {
	int val;
	int step;
}st, ed;

int main() {
	int n, k;
	queue<node>q;
	while(~scanf("%d%d", &n, &k)) {
		st.val = n;
		st.step = 0;
		vis[n] = 1;
		q.push(st);
		while(!q.empty()) {
			st = q.front();
			q.pop();
			if(st.val == k) {
				printf("%d
", st.step);
				continue;
			}
			for(int i = 0; i < 3; i++) {
				if(i == 0) {
					ed.val = st.val + 1;
					if(vis[ed.val]==0) {
						ed.step = st.step + 1;
						vis[ed.val] = 1;
						q.push(ed);
					}
				}
				else if(i == 1) {
					ed.val = st.val - 1;
					if(ed.val >= 0 && vis[ed.val] == 0) {
						ed.step = st.step + 1;
						vis[ed.val] = 1;
						q.push(ed);
					}
				}
				else if(i == 2) {
					ed.val = st.val * 2;
					if(ed.val < 2 * k  && vis[ed.val] == 0)  {
						ed.step = st.step + 1;
						vis[ed.val] = 1;
						q.push(ed);
					}
				}
			}

		}
		memset(vis, 0, sizeof(vis));
	}
	return 0;
}

未完!

原文地址:https://www.cnblogs.com/smuzoey/p/11787445.html