作业介绍

/*
  BFS搜索,A*优化

  八数码问题无解当且仅当
	  展开以后,逆序对的数量是奇数

  估价函数:1~8每个数和最终位置的曼哈顿距离之和

 */
#include <bits/stdc++.h>
using namespace std;
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
typedef pair <int, string> PIS;
char ch;
string start, s;

// 计算估价函数
int f (string state) {
	int ans = 0;
	for (int i = 0; i < 9; i++) {
		if (state[i] == '0') continue;
		int t = state[i] - '1';
		ans += abs (i / 3 - t / 3) + abs (i % 3 - t % 3);
	}
	return ans;
}
int Astar () {
	string end = "123804765";
	unordered_map <string, int> dist;  // 记录当前距离
	priority_queue <PIS, vector <PIS>, greater <PIS>> heap;
	dist[start] = 0;
	heap.push ({f (start), start});
	while (!heap.empty ()) {

		auto t = heap.top ();
		heap.pop ();
		string state = t.second;
		if (state == end) break;  // 提前退出
		int x, y;
		for (int i = 0; i < 9; i++) { // 找到空格
			if (state[i] == '0') {
				x = i / 3, y = i % 3;
				break;
			}
		}

		string source = state;  // 保留原字符串
		for (int i = 0; i < 4; i++) {
			int a = x + dx[i], b = y + dy[i];
			if (a < 0 || a > 2 || b < 0 || b > 2) continue;
			swap (state[a * 3 + b], state[x * 3 + y]);
			if (!dist.count (state) || dist[state] > dist[source] + 1) {
				dist[state] = dist[source] + 1;
				heap.push ({dist[state] + f(state), state});
			}
			state = source;  // 还原原来的字符串
		}
	}
	return dist[end];
}
int main () {
	for (int i = 0; i < 9; i++) {
		cin >> ch;
		start += ch;
		if (ch != '0') s += ch;
	}
	cout << Astar () << endl;
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N  = 888;
int n, m, T, ans;
char a[N][N];
pair<int, int > boy, girl, gui[3];

int dx[] = {0, 0, 1, -1};

int dy[] = {1, -1, 0, 0};

int st[N][N] ; // st[i][j] =1 ,代表男孩到过, =2, 代表女孩到过

bool check(int x, int y, int step) {
	if (x < 1 || x > n || y < 1 || y > m)
		return 0;
	if (a[x][y] == 'X')
		return 0;
	// 判断有没有鬼
	for (int i = 1; i <= 2; i++) { // 判断曼哈顿距离
		if (abs(gui[i].first - x) + abs(gui[i].second - y) <= step * 2)
			return 0;
	}
	return 1;
}



// 双向BFS
bool bfs() {
	memset(st, 0, sizeof st);
	queue<pair<int, int > >q1, q2; // 两个队列
	q1.push(boy), q2.push(girl);
	int step = 0;
	while (q1.size() || q2.size()) {
		step++;
		// 男生
		for (int i = 1; i <= 3; i++) {
			for (int j = 0, len = q1.size() ; j < len; j++) {
				auto t  = q1.front();
				q1.pop();
				for (int k = 0; k < 4; k++) {
					int nx = t.first + dx[k], ny = t.second + dy[k];
					if (check(nx, ny, step) == 0)
						continue;
					if (st[nx][ny] == 2) {
						ans = step;
						return 1;
					}
					if (!st[nx][ny]) {
						st[nx][ny] = 1;
						q1.push({nx, ny});
					}
				}
			}
		}
		// 女生
		for (int i = 1; i <= 1; i++) {
			for (int j = 0, len = q2.size() ; j < len; j++) {
				auto t  = q2.front();
				q2.pop();
				for (int k = 0; k < 4; k++) {
					int nx = t.first + dx[k], ny = t.second + dy[k];
					if (check(nx, ny, step) == 0)
						continue;
					if (st[nx][ny] == 1) {
						ans = step;
						return 1;
					}
					if (!st[nx][ny]) {
						st[nx][ny] = 2;
						q2.push({nx, ny});
					}
				}
			}
		}
	}
	return 0;
}

int main() {
	cin >> T;
	while (T--) {
		cin >> n >> m;
		int cnt = 0;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++) {
				cin >> a[i][j];
				if (a[i][j] == 'M')
					boy.first = i, boy.second = j;
				if (a[i][j] == 'G')
					girl.first = i, girl.second = j;
				if (a[i][j] == 'Z')
					gui[++cnt].first = i, gui[cnt].second = j;
			}
		if (bfs())
			cout << ans << endl;
		else
			cout << -1 << endl;
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 20;

struct node {
	int x, y, hp;
};
int a[N][N], n, m;
int dis[N][N][7];
int sx, sy;

int dx[] = {0, 0, 1, -1};

int dy[] = {1, -1, 0, 0};

void bfs() {
	queue<node> q;
	memset(dis, 0x3f, sizeof dis);
	dis[sx][sy][6] = 0;
	q.push({sx, sy, 6});
	while (q.size()) {
		auto t  = q.top();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int nx = t.x + dx[i];
			int ny = t.y + dy[i];
			if (nx < 1 || nx > n || ny < 1 || ny > m)
				continue;
			if (t.hp == 1)
				continue;
			int hp = t.hp - 1;
			if (a[nx][ny] == 0)
				continue;
			if (a[nx][ny] == 4)
				hp = 6;
			if (dis[nx][ny][hp] > dis[t.x][t.y][t.hp] + 1) {
				dis[nx][ny][hp] = dis[t.x][t.y][t.hp] + 1;
				q.push({nx, ny, hp});
			}
		}
	}
}



// (x,y) 时间,血量
// dis[x][y][hp] =


// 1 1 1 2 2 2  queue
// 0 1 0 1 0 1 deque
// 1 2 4 2 1 0 3  priority_queue
// deque
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
char a[N][N];

int dx[] = {-1, -1, 1, 1};

int dy[] = {-1, 1, 1, -1};

int ix[] = {-1, -1, 0, 0};

int iy[] = {-1, 0, 0, -1};
char s[] = "\\/\\/";
int dis[N][N];

int n, m;

void bfs() {
	memset(dis, 0x3f, sizeof dis);
	dis[1][1] = 0;
	deque<pair<int, int> >q;
	q.push_front({1, 1});
	while (q.size()) {
		auto t = q.front();
		q.pop_front();
		int x  = t.first, y = t.second;
		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i], ny = y + dy[i];
			if (nx < 1 || nx > n + 1 || ny < 1 || ny > m + 1)
				continue;
			int ii = x + ix[i], jj = y + iy[i];
			int w = 0;
			if (a[ii][jj] == s[i])
				w = 0;
			else
				w = 1;
			if (dis[nx][ny] > dis[x][y] + w) {
				dis[nx][ny] = dis[x][y] + w;
				if (w)
					q.push_back({nx, ny});
				else
					q.push_front({nx, ny});
			}
		}
	}
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> a[i][j];
	bfs();
	if (dis[n + 1][m + 1] == 0x3f3f3f3f)
		cout << "NO SOLUTION";
	else
		cout << dis[n + 1][m + 1];
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 510;

struct node {
	int x, y;
	int lie; // 0 站 1 横  2 竖
};
node start, end1;

int d[3][4][3] = {
	{{-2, 0, 2}, {0, 1, 1}, {1, 0, 2}, {0, -2, 1}},
	{{-1, 0, 1}, {0, 2, 0}, {1, 0, 1}, {0, -1, 0}},
	{{-1, 0, 0}, {0, 1, 2}, {2, 0, 0}, {0, -1, 2}}
};

int dis[N][N][3];
char a[N][N];
int n, m;
int bfs(node start, node end1) {
	memset(dis, -1, sizeof dis);
	dis[start.x][start.y][start.lie] = 0;
	queue<node>q;
	q.push(start);
	while (q.size()) {
		auto t = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int nx = t.x + d[t.lie][i][0];
			int ny = t.y + d[t.lie][i][1];
			int nl = d[t.lie][i][2];
			// 1. 越界
			if (nx < 1 || nx > n || ny < 1 || ny > m)
				continue;
			// 2. 不能走
			if (a[nx][ny] == '#')
				continue;
			if (nl == 0 && a[nx][ny] == 'E')
				continue;
			if (nl == 1 && (ny + 1 > m || a[nx][ny + 1] == '#' ))
				continue;
			if (nl == 2 && (nx + 1 > n || a[nx + 1][ny] == '#' ))
				continue;
			if (dis[nx][ny][nl] == -1) {
				dis[nx][ny][nl] = dis[t.x][t.y][t.lie] + 1;
				q.push({nx, ny, nl});
			}
		}
	}
	return dis[end1.x][end1.y][end1.lie];
}

int main() {
	while (cin >> n >> m, n && m) {
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++) {
				cin >> a[i][j];
				if (a[i][j] == 'O') {
					end1.x = i, end1.y = j, end1.lie = 0;
				}
			}
		// 找一下起始点
		bool flg = 0;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if (a[i][j] == 'X') {
					start.x = i, start.y = j, start.lie = 0;
					if (a[i][j + 1] == 'X')
						start.lie = 1;
					if (a[i + 1][j] == 'X')
						start.lie = 2;
					flg = 1;
					break;
				}
			}
			if (flg)
				break;
		}
		int ans = bfs(start, end1);
		if (ans == -1)
			puts("Impossible");
		else
			cout << ans << endl;
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n, k; // k = n/2
long long w;
long long a[N], ans;
vector<long long> weight;

// u 当前搜索的物品,sum 物品和
// 搜 1 - n/2
void dfs1(int u, long long sum) {
	if (u > k) {
		weight.push_back(sum);
		return ;
	}
	dfs1(u + 1, sum); // 当前物品不放进来
	if (sum + a[u] <= w)
		dfs1(u + 1, sum + a[u]); // 当前物品放进来
}

// n/2+1, n
void dfs2(int  u, long long sum) {
	if (u > n) {
		// 和之前搜索出来的 结果匹配
		long long  t = w - sum; // 要匹配的值
		auto tmp = upper_bound(weight.begin(), weight.end(), t) - weight.begin() - 1;
		if (tmp == -1)
			return ;
		else {
			ans = max(ans, weight[tmp] + sum);
			return ;
		}
	}
	dfs2(u + 1, sum);
	if (sum + a[u] <= w)
		dfs2(u + 1, sum + a[u]);
}

int main() {
	cin >> w >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	k  = n / 2;
	dfs1(1, 0);
	sort(weight.begin(), weight.end());
	dfs2(k + 1, 0);
	cout << ans;
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e2 + 10;
int n, path[N]; // path  记录路径

// now 当前放置的数字的位置
// depth 能搜索的最大深度
bool dfs(int now, int depth) {
	// path[0] =1 , path[now-1] == n
	if (now == depth)
		return path[now - 1] == n;
	// 判重
	bool st[110] = {0};
	// 放 now 这个位置
	// path[i] + path[j] = path[now]
	for (int i = now - 1 ; i >= 0 ; i--) {
		for (int j = i; j >= 0; j--) {
			int s = path[i] + path[j];
			if (st[s])
				continue;
			if (s > path[now - 1] && s <= n) {
				path[now] = s;
				st[s] = 1;
				if (dfs(now + 1, depth))
					return 1;
			}
		}
	}
	return 0;
}

int main() {
	while (cin >> n, n) {
		int depth = 1;
		path[0] = 1;
		while (!dfs(1, depth))
			depth++;
		for (int i = 0; i < depth; i++)
			cout << path[i] << " ";
		cout << endl;
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, a[N], w;
int c[N], ans = 1e9;

// now 当前小猫的编号, cnt 缆车数量
void dfs(int now, int cnt) {
	// 最优性减枝
	if (cnt >= ans)
		return ;
	if (now == n + 1) {
		ans = min(ans, cnt);
		return ;
	}
	for (int i = 1; i <= cnt; i++) {
		if (c[i] + a[now] <= w) {
			c[i] += a[now];
			dfs(now + 1, cnt);
			c[i] -= a[now];
		}
	}
	c[cnt + 1] = a[now];
	dfs(now + 1, cnt + 1);
	c[cnt + 1] = 0;
}


int main() {
	cin >> n >> w;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	sort(a + 1, a + 1 + n, greater<int>());
	dfs(1, 0);
	cout << ans;
	return 0;
}

题目

认领作业后才可以查看作业内容。
状态
正在进行…
题目
9
开始时间
2026-8-1 0:00
截止时间
2026-12-31 23:59
可延期
24 小时