ZOJ 1005 Jugs

原题地址: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;
    }
}

猜你喜欢

转载自silentdusk.iteye.com/blog/1523751
ZOJ
今日推荐