非常可乐
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3009 Accepted Submission(s): 1221
Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
Sample Input
7 4 3 4 1 3 0 0 0
Sample Output
NO 3
package acm.hdu;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @Description Hdu ACM 1495 非常可乐
*
* @author Alex
* @Date 20130427
* @Time 19:42
* @Result Accept
*/
public class Hdu1495_20130429_1828 {
private static int [][][] array = null; //存储状态是否出现过,出现置值为1否则为0
private static int [] capacity = null; //存储三个容量
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int s,n,m;
while(true){
s = in.nextInt();
n = in.nextInt();
m = in.nextInt();
capacity = new int[3];
if(s == 0 && m == 0 && n == 0){
break;
}
array = new int[s+1][n+1][m+1];
array[s][0][0] = 1; //置初始状态下为1
capacity[0] = s; //设置个个杯子的容量
capacity[1] = n;
capacity[2] = m;
State state = new State(s,0,0); //生成初始状态
state.setCount(0);
int count = solve(state);
if(count != -1){
System.out.println(count);
}else{
System.out.println("NO");
}
}
}
/**
* 判断是否可以解决,
* @param s 初始状态
* @return 如果可以解决,返回解决需要的步骤,否则返回 -1
*/
private static int solve(State s){
int i,j;
Queue<State> queue = new LinkedBlockingQueue<State>();
queue.add(s);
while(!queue.isEmpty()){
s = queue.poll();
for(i = 0; i < s.getCoco().length; ++i){ //杯子 i 向杯子 j 倒入
for(j = 0; j < s.getCoco().length; ++j){
if(i != j){
State temp = new State();
temp.setCount(s.getCount()+1);
if(s.getCoco(i) + s.getCoco(j) > capacity[j]){
temp.setCoco(i, s.getCoco(i) - capacity[j] + s.getCoco(j));
temp.setCoco(j, capacity[j]);
temp.setCoco(3-i-j, s.getCoco(3-i-j));
}else{
temp.setCoco(i, 0);
temp.setCoco(j, s.getCoco(i) + s.getCoco(j));
temp.setCoco(3-i-j, s.getCoco(3-i-j));
}
if(array[temp.getCoco(0)][temp.getCoco(1)][temp.getCoco(2)] != 1){ //如果当前状态没有出现过
if(isResult(temp)){ //判断当前状态是不是结束状态,如果是返回达到当前状态需要的步骤。
return temp.getCount();
}
queue.add(temp);
array[temp.getCoco(0)][temp.getCoco(1)][temp.getCoco(2)] = 1;
}
}
}
}
}
return -1;
}
/**
* 判断状态是否为结束状态。
* @param state 当前状态
* @return 如果为结束状态,刚返回 true, 否则返回 false
*/
private static boolean isResult(State state){
int v1 = state.getCoco(0);
int v2 = state.getCoco(1);
int v3 = state.getCoco(2);
if((v1 == v2 && v3 == 0)||(v1 == v3 && v2 == 0)||(v3 == v2 && v1 == 0)){
return true;
}
return false;
}
}
/**
* 状态
* @author Administrator
*
*/
class State{
private int [] coco = null;
private int count = 0;
public State(){
coco = new int[3];
}
public State(int v1, int v2, int v3){
coco = new int[3];
coco[0] = v1;
coco[1] = v2;
coco[2] = v3;
}
public int getCoco(int index){
if(index >=0 && index < 3)
return coco[index];
return -1;
}
public void setCoco(int index, int value){
coco[index] = value;
}
public int getCount(){
return count;
}
public void setCount(int count){
this.count = count;
}
public int[] getCoco(){
return coco;
}
}