专题一 简单搜索

A 棋盘问题

我就是一个智障,总是把变量弄错,导致浪费了很多时间
用简单的回溯法,就可以暴力破解
我的代码:


#include<cstdio> 

using namespace std;

const int MAXN = 9;

bool col[MAXN];
char qipan[MAXN][MAXN];
int n, maxk;
int ans = 0;

bool read () {
	scanf("%d %d", &n, &maxk);
	if (n == -1) return false;
	ans = 0;
	for (int i = 0; i < n; i++) {
		scanf("%s", qipan[i]);
	}
	return true;
}

void dfs (int i, int cur) {
	if (cur == maxk) {
		ans++;
		return;
	}
	for (int k = i; k <= n-maxk+cur; k++) {
		for (int j = 0; j < n; j++) {
			if (!col[j] && qipan[k][j] == '#') {
				col[j] = true;
				dfs(k+1, cur+1);
				col[j] = false;
			}
		}
	}
}

int main () {
	while (read()) {
		dfs(0, 0);
		printf("%d\n", ans);
	}
}

B Dungeon Master

使用bfs就可以了
我的代码:

#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int MAXN = 32;
const int MAXD = 6;
const int di[] = {0, 0, 0, 0, 1, -1}; // i是控制上下 
const int dj[] = {1, -1, 0, 0, 0, 0}; // j是控制前后
const int dk[] = {0, 0, 1, -1, 0, 0}; // k是控制左右 

char migong[MAXN][MAXN][MAXN];
int d[MAXN][MAXN][MAXN], L, R, C, si, sj, sk;

bool read () {
	scanf("%d %d %d", &L, &R, &C);
	if (L == 0) return 0;
	for (int i = 0; i < L; i++) {
		for (int j = 0; j < R; j++) {
			scanf("%s", migong[i][j]);
			for (int k = 0; k < C; k++) {
				if (migong[i][j][k] == 'S') {
					si = i; sj = j; sk = k;
				} 
			}
		}
	}
	memset(d, -1, sizeof(d));
	return true;
}

bool inside (int i, int j, int k) {
	return i >= 0 && j >= 0 && k >= 0 && i < L && j < R && k < C;
}

int bfs () {
	queue<int> qi, qj, qk;
	qi.push(si); qj.push(sj); qk.push(sk);
	d[si][sj][sk] = 0;
	while (!qi.empty()) {
		int i = qi.front(), j = qj.front(), k = qk.front();
		qi.pop(); qj.pop(); qk.pop();
		for (int l = 0; l < MAXD; l++) {
			int ni = i+di[l], nj = j+dj[l], nk = k+dk[l];
			if (inside(ni, nj, nk) && d[ni][nj][nk] == -1) {
				if (migong[ni][nj][nk] == '.') {
					d[ni][nj][nk] = d[i][j][k]+1;
					qi.push(ni); qj.push(nj); qk.push(nk);
				} else if (migong[ni][nj][nk] == 'E') {
					return d[i][j][k]+1;
				}
			}
		}
	}
	return 0;
}

int main () {
	while (read()) {
		int ans = bfs();
		if (ans == 0) {
			printf("Trapped!\n");
		} else {
			printf("Escaped in %d minute(s).\n", ans);
		}
	}
}

C Find The Multiple

这道题,一开始是没有什么思路的,看了别人的解答过程,才有的思路,主要是涉及了关于数学的运算
手动模拟一下除法的过程,就会发现:上一位的除法剩下的余数乘以10,会进入下一位的除法运算的运算

我的代码:

#include<cstdio>

using namespace std;

const int MAXN = 100;

int p[MAXN], len, n;

bool dfs (int cur, int r) {
	if (cur < MAXN) {
		p[cur] = 1;
		if ((r*10+1)%n == 0) {
			len = cur+1;
			return true;
		}
		if (dfs(cur+1, (r*10+1)%n)) {
			return true;
		}
		p[cur] = 0;
		if ((r*10)%n == 0) {
			len = cur+1;
			return true;
		}
		if (dfs(cur+1, (r*10)%n)) {
			return true;
		}
	}
	return false;
}

int main () {
	while (scanf("%d", &n) && n != 0) {
		dfs(0, 0);
		for (int i = 0; i < len; i++) {
			printf("%d", p[i]);
		}
		printf("\n");
	}
}

D Prime Path

先把所有素数都存储下来,然后再用bfs寻找最短路径

我的代码:

#include<cstdio>
#include<cstring> 
#include<cmath>
#include<queue> 

using namespace std;

const int MAXN = 10;

bool prime[MAXN][MAXN][MAXN][MAXN];
int d[MAXN][MAXN][MAXN][MAXN], start[4], goal[4];

void calPrime () {
	int index[4];
	for (int i = 9999; i >= 1000; i--) {
		bool ok = true;
		if (i == 8179) {
			int k = 0;
		}
		for (int j = sqrt(i); j > 1; j--) {
			if (i%j == 0) {
				ok = false;
				break;
			}
		}
		if (ok) {
			for (int j = 3, num = i; j >= 0; j--, num = num/10) {
				index[j] = num%10;
			}
			prime[index[0]][index[1]][index[2]][index[3]] = true;
		}
	}
}

int bfs () {
	queue<int> q0, q1, q2, q3;
	int num[4];
	q0.push(start[0]); q1.push(start[1]); q2.push(start[2]); q3.push(start[3]);
	d[start[0]][start[1]][start[2]][start[3]] = 0;
	while (!q0.empty()) {
		num[0] = q0.front(), num[1] = q1.front(), num[2] = q2.front(), num[3] = q3.front();
		q0.pop(); q1.pop(); q2.pop(); q3.pop();
		int depth = d[num[0]][num[1]][num[2]][num[3]];
		if (num[0] == goal[0] && num[1] == goal[1] && num[2] == goal[2] && num[3] == goal[3]) return depth;
		for (int i = 0; i < 4; i++) {
			int flag = num[i];
			for (num[i]; num[i] >= 0; num[i]--) {
				if (prime[num[0]][num[1]][num[2]][num[3]] && d[num[0]][num[1]][num[2]][num[3]] == -1) {
					d[num[0]][num[1]][num[2]][num[3]] = depth+1;
					q0.push(num[0]); q1.push(num[1]); q2.push(num[2]); q3.push(num[3]);
				}
			}
			num[i] = flag;
			for (num[i]; num[i] < 10; num[i]++) {
				if (prime[num[0]][num[1]][num[2]][num[3]] && d[num[0]][num[1]][num[2]][num[3]] == -1) {
					d[num[0]][num[1]][num[2]][num[3]] = depth+1;
					q0.push(num[0]); q1.push(num[1]); q2.push(num[2]); q3.push(num[3]);
				}
			}
			num[i] = flag;
		}
	}
	return -1;
}

int main () {
	calPrime();
	int T;
	scanf("%d", &T);
	while (T--) {
		int a, b;
		scanf("%d %d", &a, &b);
		memset(d, -1, sizeof(d));
			for (int i = 3, num1 = a, num2 = b; i >= 0; i--, num1 = num1/10, num2 = num2/10) {
				start[i] = num1%10;
				goal[i] = num2%10;
			}
		int ans = bfs();
		printf("%d\n", ans);
	}
	return 0;
}

E Shuffle’m Up

比起简单搜索更像是模拟题,用set记录那些遍历过的数据,如果产生循环,则结果是不可能到达的,输出-1

我的代码:

#include<iostream> 
#include<string>
#include<set>

using namespace std;

const int MAXC = 200;

int C;
string p1, p2, p, ans;
set<string> cache;

int solve () {
	for (int cnt = 1; ; cnt++) {
		for (int i = 0; i < C; i++) { // 把p2放在下面 
			p[i*2+1] = p1[i];
			p[i*2] = p2[i];
		}
		if (ans == p) return cnt;
		if (cache.count(p)) return -1;
		cache.insert(p);
		p1 = p.substr(0, C);
		p2 = p.substr(C, C);
	}
}

int main () {
	int T;
	cin >> T;
	for (int t = 1; t <= T; t++) {
		cin >> C;
		cache.clear();
		getline(cin, p1);
		getline(cin, p1);
		getline(cin, p2);
		p = p1+p2;
		getline(cin, ans);
		int ans = solve();
		cout << t << " " << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值