迭代深搜

迭代深搜简单来说就是限制深度的深搜,这样就可以避免像广搜一样占用大量空间,又可以像广搜找到最佳的路径。

两道例题

1.埃及分数

#include<cstdio>
#include<set>
#include<cstring>
using namespace std;

const int N = 10;
typedef long long LL;

set<LL>s;
LL now[N], pre[N];
bool flag;

LL gcd(LL a, LL b) {
	return b ? gcd(b, a%b) : a;
}

bool good(int k) {//比较出较好的结果
	for (int i = k; i>0; i--) {
		if (now[i] != pre[i]) {
			return pre[i] == 0 || now[i] < pre[i];
		}
	}
	return 0;
}

void dfs(LL a, LL b, int k, int dep) {
	if (k == dep) {
		if (b%a ||b/a<=now[k-1]||s.count(b/a)) {
			return;
		}
		now[k] = b / a;
		if (!flag || good(k)) {
			memcpy(pre, now, sizeof(now));
		}
		flag = 1;
		return;
	}
	LL j = b / a;
	if (j <= now[k - 1]) {
		j = now[k - 1] + 1;
	}
	LL t = (dep - k + 1)*b / a;//如果不满足,那么永远不可能有结果,所以就可以限制上限
	for (LL i = j; i <= t; i++) {
		if (s.count(i)) {
			continue;
		}
		now[k] = i;
		LL m = gcd(a*i - b, b*i);
		dfs((a*i - b) / m, b*i / m, k + 1, dep);
	}
}

void fun(LL a, LL b) {
	now[0] = 1;
	for (int dep = 2; dep <= N; dep++) {
		dfs(a, b, 1, dep);
		if (flag) {
			for (int i = 1; i <= dep; i++) {
				if (i != dep) {
					printf("1/%lld+", pre[i]);
				}
				else {
					printf("1/%lld", pre[i]);
				}
			}
			printf("\n");
			return;
		}
	}
}

int main() {
	int T;
	scanf("%d", &T);
	for (int i = 1; i <= T; i++) {
		memset(now, 0, sizeof(now));
		memset(pre, 0, sizeof(pre));
		s.clear();
		LL a, b;
		int k, t;
		flag = 0;
		scanf("%lld%lld%d", &a, &b, &k);
		while (k--) {
			scanf("%d", &t);
			s.insert(t);
		}
		printf("Case %d: %lld/%lld=", i, a, b);
		fun(a, b);
	}
	return 0;
}

2.

这道题没有过oj,就纯过了样例,但重要的是理解迭代深搜的思想。

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std;

int arr[8][8];
int num;
vector<char> vec;

char name(int x, int y, int dir) {
	if (y) {
		if (dir == -1) {
			if (y == 2) {
				return 'A';
			}
			else {
				return 'B';
			}
		}
		else if (dir == 1) {
			if (y == 2) {
				return 'F';
			}
			else {
				return 'E';
			}
		}
	}
	else if (x) {
		if (dir == 1) {
			if (x == 2) {
				return 'C';
			}
			else {
				return 'D';
			}
		}
		else if (dir == -1) {
			if (x == 2) {
				return 'H';
			}
			else {
				return 'G';
			}
		}
	}
}

int judge() {
	int x = arr[2][2];
	for (int j = 2; j <= 4; j += 2) {
		for (int i = 2; i <= 4; i++) {
			if (arr[j][i] != x) {
				return 0;
			}
		}
	}
	for (int i = 2; i <= 4; i += 2) {
		if (arr[3][i] != x) {
			return 0;
		}
	}
	return x;
}

void move(int x, int y, int dir) {
	if (y != 0) {
		if (dir<0) {
			int t = arr[6][y];
			for (int i = 0; i<6; i++) {
				arr[(i + dir + 7) % 7][y] = arr[i][y];
			}
			arr[5][y] = t;
		}
		else if (dir>0) {
			int t = arr[0][y];
			for (int i = 6; i>0; i--) {
				arr[(i + dir + 7) % 7][y] = arr[i][y];
			}
			arr[1][y] = t;
		}
	}
	else if (x != 0) {
		if (dir<0) {
			int t = arr[x][6];
			for (int i = 0; i<6; i++) {
				arr[x][(i + dir + 7) % 7] = arr[x][i];
			}
			arr[x][5] = t;
		}
		else if (dir>0) {
			int t = arr[x][0];
			for (int i = 6; i>0; i--) {
				arr[x][(i + dir + 7) % 7] = arr[x][i];
			}
			arr[x][1] = t;
		}
	}
}

void dfs(int k, int dep) {
	if (k == dep) {
		int j = judge();
		if (j) {
			num = j;
			return;
		}
		return;
	}
	for (int i = 2; i <= 4; i += 2) {
		if (num != -1) {
			return;
		}
		move(0, i, -1);
		vec.push_back(name(0, i, -1));
		dfs(k + 1, dep);
		if (num != -1) {
			return;
		}
		vec.pop_back();
		move(0, i, 1);
	}
	for (int i = 2; i <= 4; i += 2) {
		if (num != -1) {
			return;
		}
		move(i, 0, 1);
		vec.push_back(name(i, 0, 1));
		dfs(k + 1, dep);
		if (num != -1) {
			return;
		}
		vec.pop_back();
		move(i, 0, -1);
	}
	for (int i = 2; i <= 4; i += 2) {
		if (num != -1) {
			return;
		}
		move(0, i, 1);
		vec.push_back(name(0, i, 1));
		dfs(k + 1, dep);
		if (num != -1) {
			return;
		}
		vec.pop_back();
		move(0, i, -1);
	}
	for (int i = 2; i <= 4; i += 2) {
		if (num != -1) {
			return;
		}
		move(i, 0, -1);
		vec.push_back(name(i, 0, -1));
		dfs(k + 1, dep);
		if (num != -1) {
			return;
		}
		vec.pop_back();
		move(i, 0, 1);
	}
}

void iinput(int i) {
	int t;
	for (int j = 2; j <= 4; j += 2) {
		scanf("%d", &t);
		arr[i][j] = t;
	}
}

void input() {
	int t;
	scanf("%d", &t);
	arr[0][5] = t;
	iinput(1);
	for (int i = 0; i<7; i++) {
		scanf("%d", &t);
		arr[2][i] = t;
	}
	iinput(3);
	for (int i = 0; i<7; i++) {
		scanf("%d", &t);
		arr[4][i] = t;
	}
	iinput(5);
	iinput(6);
}

int main() {
	int t;
	while (scanf("%d", &t) != EOF) {
		memset(arr, 0, sizeof(arr));
		arr[0][3] = t;
		num = -1;
		vec.clear();
		input();
		for (int dep = 1; dep <= 10; dep++) {
			dfs(0, dep);
			if (num != -1) {
				break;
			}
			vec.clear();
		}
		for (int i = 0; i<vec.size(); i++) {
			cout << vec[i];
		}
		cout << endl << num << endl;
	}
	return 0;
}
posted @ 2019-10-20 12:07  夜烛灯花  阅读(199)  评论(0)    收藏  举报