【搜索】B033_oenj_Pots(新颖 / RE)

一、Problem

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  • FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
  • DROP(i) empty the pot i to the drain;
  • POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

二、Solution

大致题意:a 和 b 代表两个杯子的容量,c 是希望得到的液体体积。一开始两个杯子都是空的,如果利用两个杯子可以倒出 c 升液体则输出最小的步数和倒出 c 的步骤。

对两个杯子可以进行以下操作:

  • FILL(i):装满第 i 个杯子;
    DROP(i):清空第 i 个杯子;
    POUR(i,j):从第 i 个杯子向第 j 个杯子中倒水,若水壶 j 满了,则 i 剩下的就不倒了

方法一:bfs

  • 第一步:定义存储每一个状态信息的 Info 类。
  • 第二步:编写放水逻辑,每一次出队记录前驱到当前信息 cur 的成员变量 pre。

  • Q1:问题一:注意 java 的引用传递机制:
    A1:
  • Q2:问题二:为什么得到一个 RE:
    A2:
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static int a, b, c;
	static boolean[][] vis;
	static Stack<Integer> st;
	static int bfs(int x, int y) {
		Info info = new Info();
		info.x = x; info.y = y; info.step = 0; info.op = -1;
		Queue<Info> q = new ArrayDeque<>();
		q.add(info);
		st = new Stack<>();
		
		while (!q.isEmpty()) {
			Info t = q.poll();
			//Info cur = t;			注
			Info cur = new Info(t);
			if (vis[cur.x][cur.y])
				continue;
			vis[cur.x][cur.y] = true;
			for (int k = 1; k <= 6; k++) {
				if (k == 1) {	//倒满a
					cur.x = a;
					cur.y = t.y;
					cur.op = k;
				}else if (k == 2) {	//倒满b
					cur.x = t.x;
					cur.y = b;
					cur.op = k;
				}else if (k == 3) {	//舍弃a
					cur.x = 0;
					cur.y = t.y;
					cur.op = k;
				}else if (k == 4) {	//舍弃b
					cur.x = t.x;
					cur.y = 0;
					cur.op = k;
				}else if (k == 5) {	        //倒满b
					int need = b - t.y;
					if (t.x > need) {		//判断a是否可倒满b
						cur.x = t.x - need;
						cur.y = b;
					} else {
						cur.x = 0;
						cur.y = t.y + t.x;
					}
					cur.op = k;
				}else if (k == 6) {			//倒满a
					int need = a - t.x;
					if (t.y > need) {		//判断a是否可倒满b
						cur.y = t.y - need;
						cur.x = a;
					} else {
						cur.y = 0;
						cur.x = t.x + t.y;
					}
					cur.op = k;
				}
				cur.step = t.step + 1;
				cur.pre = t;
				q.add(new Info(cur)); 	//q.add(cur); 注
				if (cur.x == c || cur.y == c) {
					int res = cur.step;
					while (cur.pre != null) {
						st.push(cur.op);
						cur = cur.pre;
					}
					return res;
				}
			}
		}
		return -1;
	}
    public static void main(String[] args) throws IOException {  
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(System.out));
		a = sc.nextInt();
		b = sc.nextInt();
		c = sc.nextInt();
		vis = new boolean[b+50][b+50];
		int res = bfs(0, 0);
		if (res == -1) 
			System.out.println("impossible");
		else {
		    System.out.println(res);
			while (!st.isEmpty()) {
				int op = st.pop();
				if (op == 1) System.out.println("FILL(1)");
				if (op == 2) System.out.println("FILL(2)");
				if (op == 3) System.out.println("DROP(1)");
				if (op == 4) System.out.println("DROP(2)");
				if (op == 5) System.out.println("POUR(1,2)");
				if (op == 6) System.out.println("POUR(2,1)");
			}
		}
    }
	static class Info {
		int x, y, step, op;	//xy记录两个杯子的水量
		Info pre;
		Info() {}
		Info(Info t) {
		    this.x = t.x; this.y = t.y; this.step = t.step; this.op = t.op;
		    this.pre = t.pre;
		}
	}
}

复杂度分析

  • 时间复杂度: O ( R × C ) O(R × C)
  • 空间复杂度: O ( R × C ) O(R × C)
发布了714 篇原创文章 · 获赞 199 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/105635220
re