南阳理工ACM 题目21 三个水杯 java代码 广度优先

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
 static class Node
 {
  int water[]=new int[3];//水杯水
  int step;//步骤
 }
 static class M
 {
  boolean visted[][][];//标记水杯的状态
  int start[];//输入状态
  int end[];//输出状态
  void init()//初始化
  {
   Scanner aa=new Scanner(System.in);
   int N=aa.nextInt();
   while(N--!=0)
   {
    start=new int[3];
    end=new int[3];
    visted=new boolean[100][100][100];
    for(int i=0;i<3;i++)
    {
     start[i]=aa.nextInt();
    }
    for(int i=0;i<3;i++)
    {
     end[i]=aa.nextInt();
    }
    int k=BFS();
    System.out.println(k);
   }
   
  }
  int achieve(Node node)         //判断是否到达结束状态
  {
   for(int i = 0; i < 3; i++)
   {
    if(node.water[i] != end[i])
     return 0;
   }
   return 1;
  }
  int BFS()//广度优先
  {
   Queue<Node> queue=new LinkedList<Node>();//生成队列
   Node s1=new Node();
   s1.water[0]=start[0];
   s1.water[1]=0;
   s1.water[2]=0;
   s1.step=0;
   queue.offer(s1);
   visted[start[0]][0][0]=true;
   while(!queue.isEmpty())
   {
    Node node=queue.element();//获得第一个元素
    queue.poll();//删除第一个元素
    
    if(achieve(node)==1)//判断是否符合条件
    {
     return node.step;
    }
    for(int i=0;i<3;i++)//将水从第i个杯子倒到第j个杯子
    {
     for(int j=0;j<3;j++)
     {
      if(i==j)
       continue;
      if(node.water[i]!=0&&node.water[j]<start[j])//倒水的杯子必须有谁=水,并且接水的杯子的水量不能超过上限
      {
       Node node2=new Node();
       node2.step=node.step;
       node2.water[0]=node.water[0];
       node2.water[1]=node.water[1];
       node2.water[2]=node.water[2];
       int pour=start[j]-node2.water[j];//要倒的水量
       if(node2.water[i]>=pour)//不会倒空
       {
        
        node2.water[j]+=pour;
        node2.water[i]-=pour;
       }
       else//倒空
       {
        node2.water[j]+=node2.water[i];
        node2.water[i]=0;
        
       }
       node2.step=node.step+1;
       if(!visted[node2.water[0]][node2.water[1]][node2.water[2]])//如果这种情况没有出现
       {
        visted[node2.water[0]][node2.water[1]][node2.water[2]]=true;
        queue.add(node2);//入队
       }
       
       
      }
     }
    }
   }
   return -1;
  }
 }
 public static void main(String str[])
 {
  M m=new M();
  m.init();
 }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值