原题地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1005
不贴英文了,题目简单
就是两个水杯
A升 和 B升的
。。如何让一个杯子充满C升的水,任意一个都行
不明白的话,去看虎胆龙威3.。里面那个胖子搞BOMB那段,炸学校那个
然后把如何倒的,输出来。
我的做法,好吧。代码比较凌乱,其实就是一个一个试,倒来倒去,然后倒出结果
广度优先搜索,学术名称叫这个
贴代码:
import java.util.LinkedList;
import java.util.Scanner;
public class Main{
private static String FILL_A = "fill A";
private static String FILL_B = "fill B";
private static String POUR_A_B = "pour A B";
private static String POUR_B_A = "pour B A";
private static String EMPTY_B = "empty B";
private static String EMPTY_A = "empty A";
private static String SUCCESS = "success";
private static Bucket bucketA = null;
private static Bucket bucketB = null;
private static boolean seekResult = false;
private static LinkedList<Operation> currentOperList = null;
private static int target = 0;
private static Operation lastOperation = null;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String a = in.nextLine();
String[] params = a.split(" ");
int cap1 = Integer.parseInt(params[0]);
int cap2 = Integer.parseInt(params[1]);
int target = Integer.parseInt(params[2]);
init(cap1, cap2, target);
seekSolution();
outResult();
}
}
private static void outResult() {
LinkedList<String> resultList = new LinkedList<String>();
Operation operation = lastOperation;
resultList.addFirst(operation.getOperation());
while(operation.getParent()!=null){
operation = operation.getParent();
resultList.addFirst(operation.getOperation());
}
resultList.addLast(SUCCESS);
for(String result: resultList){
System.out.println(result);
}
}
private static boolean checkResult() {
if (bucketA.getWater() == target || bucketB.getWater() == target) {
return true;
} else {
return false;
}
}
private static void seekSolution() {
if(seekResult){
return;
}
for (Operation op : currentOperList) {
//recover the operation's status.....
recoverStatus(op.getStatus());
//fire the operation.....
if (op.getOperation().equals(FILL_A)) {
bucketA.fill();
} else if (op.getOperation().equals(FILL_B)) {
bucketB.fill();
} else if (op.getOperation().equals(POUR_A_B)) {
bucketA.pour(bucketB);
} else if (op.getOperation().equals(POUR_B_A)) {
bucketB.pour(bucketA);
} else if (op.getOperation().equals(EMPTY_A)) {
bucketA.clear();
} else if (op.getOperation().equals(EMPTY_B)) {
bucketB.clear();
}
//check the status....
if(checkResult()){
//has found the result....
seekResult = true;
//record the last operation....
lastOperation = op;
//just return......
return;
}
}
//if the code....can reach here.....means..we need next turn..
int i = currentOperList.size();
//next turn.....
for(int j=0;j<i;j++){
Operation op = currentOperList.getFirst();
recoverStatus(op.getStatus());
//fire the operation.....
if (op.getOperation().equals(FILL_A)) {
bucketA.fill();
} else if (op.getOperation().equals(FILL_B)) {
bucketB.fill();
} else if (op.getOperation().equals(POUR_A_B)) {
bucketA.pour(bucketB);
} else if (op.getOperation().equals(POUR_B_A)) {
bucketB.pour(bucketA);
} else if (op.getOperation().equals(EMPTY_A)) {
bucketA.clear();
} else if (op.getOperation().equals(EMPTY_B)) {
bucketB.clear();
}
if (!bucketA.isFull()) {
//fill a can be inserted...
Operation fillA = new Operation();
fillA.setParent(op);
fillA.setStatus(recordStatus());
fillA.setOperation(FILL_A);
currentOperList.add(fillA);
}
if (!bucketB.isFull()) {
//fill b can be inserted
Operation fillB = new Operation();
fillB.setParent(op);
fillB.setStatus(recordStatus());
fillB.setOperation(FILL_B);
currentOperList.add(fillB);
}
if (!bucketA.isEmpty() && !bucketB.isFull()) {
//pour a to be.....
Operation pourAB = new Operation();
pourAB.setParent(op);
pourAB.setStatus(recordStatus());
pourAB.setOperation(POUR_A_B);
currentOperList.add(pourAB);
}
if (!bucketB.isEmpty() && !bucketA.isFull()) {
//pour b to a
Operation pourBA = new Operation();
pourBA.setParent(op);
pourBA.setStatus(recordStatus());
pourBA.setOperation(POUR_B_A);
currentOperList.add(pourBA);
}
if (!bucketA.isEmpty()) {
//clear a
Operation clearA = new Operation();
clearA.setParent(op);
clearA.setStatus(recordStatus());
clearA.setOperation(EMPTY_A);
currentOperList.add(clearA);
}
if (!bucketB.isEmpty()) {
//clear b
Operation clearB = new Operation();
clearB.setParent(op);
clearB.setStatus(recordStatus());
clearB.setOperation(EMPTY_B);
currentOperList.add(clearB);
}
currentOperList.removeFirst();
}
//next level!!!!
seekSolution();
}
public static void recoverStatus(Status status) {
bucketA.setWater(status.getBucketA());
bucketB.setWater(status.getBucketB());
}
public static Status recordStatus() {
Status status = new Status();
status.setBucketA(bucketA.getWater());
status.setBucketB(bucketB.getWater());
return status;
}
private static void init(int cap1, int cap2, int target2) {
// set up first bucket
bucketA = new Bucket(cap1);
// set up second bucket
bucketB = new Bucket(cap2);
// set up target
target = target2;
// set up result
seekResult = false;
// set up operlist
currentOperList = new LinkedList<Operation>();
// we put two new Operation to fire the seeking....
Operation fillAoper = new Operation();
fillAoper.setStatus(new Status(0, 0));
fillAoper.setOperation(FILL_A);
currentOperList.add(fillAoper);
Operation fillBoper = new Operation();
fillBoper.setStatus(new Status(0, 0));
fillBoper.setOperation(FILL_B);
currentOperList.add(fillBoper);
}
}
class Operation {
private String operation;
private Operation parent;
private Status status;
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public Operation getParent() {
return parent;
}
public void setParent(Operation parent) {
this.parent = parent;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
class Status {
int bucketA;
int bucketB;
public int getBucketA() {
return bucketA;
}
public void setBucketA(int bucketA) {
this.bucketA = bucketA;
}
public int getBucketB() {
return bucketB;
}
public void setBucketB(int bucketB) {
this.bucketB = bucketB;
}
public Status() {}
public Status(int a, int b) {
this.bucketA = a;
this.bucketB = b;
}
}
class Bucket {
public Bucket(int capacity) {
this.capacity = capacity;
}
private int capacity = 0;
private int water = 0;
public void fill() {
water = capacity;
}
public void clear() {
water = 0;
}
public void pour(Bucket target) {
water = target.receive(water);
}
public int receive(int inWater) {
if (inWater + water > capacity) {
int surplus = inWater + water - capacity;
fill();
return surplus;
} else {
water += inWater;
return 0;
}
}
public int getWater() {
return water;
}
public void setWater(int water) {
this.water = water;
}
public boolean isFull() {
if (water == capacity) {
return true;
}
return false;
}
public boolean isEmpty() {
if (water == 0) {
return true;
}
return false;
}
}