Pots POJ - 3414(BFS+输出路径)

题目传送门

题目描述:

给你两个壶A和B,和一个整数C。有三种操作:
1.将一个壶装满。
2.将一个壶倒空。
3.将壶i的水倒入壶j中(要么壶j满了,壶i中可能还有一些水;要么壶i空了,其所有水都被移到壶j中)。
求这些操作的最短序列,使其中一个壶中的水正好为C。输出的第一行必须包含操作序列的长度K,下面的K行必须分别描述一个操作。

思路:

显然是BFS+路径回溯
六种操作:
1.将A壶装满。
2.将B壶装满。
3.将A壶倒空。
4.将B壶倒空。
5.将A壶中的水倒入B壶中。
6.将B壶中的水倒入A壶中。
拿BFS跑这六种操作,顺便记录下路径,再DFS出路径即可。

Code:

struct node {
    
    
	int x, y, op;
};
struct pt{
    
    
	int x, y, op, step;
} path[105][105];
char str[][10] = {
    
     "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)",  "POUR(2,1)", "POUR(1,2)"};
int A, B, C;
int v[105][105];
void dfs(int x, int y) {
    
     // 输出路径
	int a = path[x][y].x;
	int b = path[x][y].y;
	if (path[x][y].step == 0) {
    
     
		if (a == A)
			cout << str[0] << endl;
		if (b == B)
			cout << str[1] << endl; 
		return;
	}
	dfs(a, b);
	cout << str[path[x][y].op]<<  endl;
}
void bfs(int v1, int v2, int L) {
    
    		
	m(v, 0);
	for (int i = 0; i < 105; i++)
		for (int j = 0; j < 105; j++)
			path[i][j].op = 0, path[i][j].step = 0, path[i][j].x = 0, path[i][j].y = 0;		
	queue <node> q;
	node start = {
    
    0, 0, 0};
	v[0][0] = 1;
	q.push(start);
	while (!q.empty()) {
    
    
		node tep = q.front();
		q.pop();
		int temp;
		if (tep.x == L || tep.y == L) {
    
    
			cout << path[tep.x][tep.y].step << endl;
			dfs(tep.x, tep.y);
			return ;
		}
		for (int i = 0; i < 6; i++) {
    
     //遍历六种情况
			if (i == 0) {
    
    
			 	start.x = v1;
				start.y = tep.y;	
			} else if (i == 2) {
    
    
				start.x = 0;
				start.y = tep.y;
			} else if (i == 1) {
    
    
				start.x = tep.x;
				start.y = v2;
			} else if (i == 3) {
    
    
				start.x = tep.x;
				start.y = 0;
			} else if (i == 5) {
    
    
				temp = tep.x + tep.y - v2;
				if (temp > 0) {
    
    
	 				start.x = temp;
	 				start.y = v2;
	 			} else {
    
    
	 				start.x = 0;
	 				start.y = tep.x + tep.y;
	 			}
			} else if (i = 4) {
    
    
			 	temp = tep.x + tep.y - v1;	
	     		if (temp > 0) {
    
    
					start.y = temp;
					start.x = v1;
				} else {
    
    
					start.y = 0;
					start.x = tep.x + tep.y;
				}
			}
			if (!v[start.x][start.y]) {
    
     //入队,记录路径
				path[start.x][start.y].x = tep.x;
				path[start.x][start.y].y = tep.y;
				path[start.x][start.y].op = i;
				path[start.x][start.y].step = path[tep.x][tep.y].step + 1;				
				v[start.x][start.y] = 1;	
				q.push(start);
			}
		}
	}
	cout << "impossible" << endl;
}
int main() {
    
    
	while (cin >> A >> B >> C) {
    
    
		bfs(A, B, C);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liudashuai666/article/details/113092284