• NYOJ21 三个水杯



    三个水杯

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:4
    描述
    给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
    输入
    第一行一个整数N(0<N<50)表示N组测试数据
    接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
    第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
    输出
    每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
    样例输入
    2
    6 3 1
    4 1 1
    9 3 2
    7 1 1
    样例输出
    3
    -1



    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.Scanner;
    /**
     * 广度优先搜索
     * @author Administrator
     *
     */
    public class n021_三个水杯 {
    	
    	public static void main(String[] args) {
    	
    		int[][] nn=getInput();
    		for(int i=0;i<nn.length;i++){
    			System.out.println(f(nn[i]));
    		}
    		
    	}
    	
    	public static int f(int[] nn){
    		//倒水次数
    		int num=0;
    		//杯子体积
    		int[] volumes=new int[3];
    		//目标状态
    		int[] goal=new int[3];
    		//当前状态
    		int[] state=new int[3];
    		//下一次倒水可能出现的所有状态
    		ArrayList<int[]> temp=new ArrayList<int[]>();
    		//历史记录
    		ArrayList<int[]> history=new ArrayList<int[]>();
    		//初始化
    		for(int i=0;i<goal.length;i++){
    			volumes[i]=nn[i];
    			goal[i]=nn[i+3];
    		}
    		state[0]=volumes[0];
    		temp.add(state.clone());
    		history.add(state.clone());
    		//
    		while(temp.size()>0){
    			
    			if(check(temp,goal)){
    				return num;
    			}
    			ArrayList<int[]> temp_n=new ArrayList<int[]>();
    			Iterator<int[]> it=temp.iterator();
    			while(it.hasNext()){
    				state=it.next();
    				for(int i=0;i<3;i++){
    					if(state[i]==0) continue;
    					for(int j=0;j<3;j++){
    						if(j==i||state[j]==volumes[j]) continue;
    						int[] t=state.clone();
    						if(t[i]-volumes[j]+t[j]>0){
    							t[i]=t[i]-volumes[j]+t[j];
    							t[j]=volumes[j];
    						}else{
    							t[j]+=t[i];
    							t[i]=0;
    						}
    						if(!check(history,t)){
    							temp_n.add(t);
    							history.add(t);
    						}
    					}
    				}
    			}
    			temp=temp_n;
    			num++;
    		}
    	
    		return -1;
    	}
    	
    	/**
    	 * 是否存在目标状态
    	 * @param temp 状态的集合 
    	 * @param goal 目标状态
    	 * @return 
    	 */
    	public static boolean check(ArrayList<int[]> temp,int[] goal){
    		for(int i=0;i<temp.size();i++){
    			if(Arrays.equals(temp.get(i), goal))
    				return true;
    		}
    		return false;
    	}
    	/**
    	 * 接收输入
    	 */
    	public static int[][] getInput(){
    		
    		Scanner scan=new Scanner(System.in);
    		int N=scan.nextInt();
    		int[][] nn=new int[N][6];
    		//0 1 2  分别存放水杯容量
    		//3 4 5  分别存放目标状态
    		for(int i=0;i<N;i++){
    			for(int j=0;j<nn[i].length;j++){
    				nn[i][j]=scan.nextInt();
    			}
    		}
    		return nn;
    	}
    }
    

    原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=21

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    [Codeforces721E]Road to Home
    [Codeforces513E2]Subarray Cuts
    [CodeForces332E]Binary Key
    [HDU4585]Shaolin
    [HDU3726]Graph and Queries
    [BZOJ3224]普通平衡树
    [BZOJ3173]最长上升子序列
    [POJ2985]The k-th Largest Group
    PHP一句话
    体验VIP版本灰鸽子,哈哈,拿到了老师的病毒教程
  • 原文地址:https://www.cnblogs.com/Jayme/p/4902360.html
Copyright © 2020-2023  润新知