1674. 倒可樂
CAT 專屬題目
中文English
給定一個容積爲 s
的裝滿可樂的瓶子和兩個容積分別爲 n
和 m
的空杯子, 其中 n + m = s
. 問能否通過在三個容器之間來回倒可樂來平分這 s
體積的可樂? 如果可以, 返回最少傾倒可樂的次數; 反之返回 -1
.
由於瓶子和杯子上沒有刻度, 所以當你從一個容器倒可樂到另一個容器中時, 只能一直倒可樂直到一個容器空了或者另一個滿了爲止.
樣例
樣例 1:
輸入: s = 4, n = 1, m = 3
輸出: 3
解釋:
首先, 從瓶子倒3體積的可樂到第二個杯子, 瓶子和兩個杯子中分別有 1, 0, 3 體積的可樂.
然後, 倒1體積的可樂從第二個杯子到第一個杯子, 此時三個容器分貝有 1, 1, 2 體積的可樂.
最後, 倒1體積的可樂從第一個杯子到瓶子, 此時瓶子和第二個杯子中都有 2 體積的可樂, 平分.
樣例 2:
輸入: s = 7, n = 4, m = 3
輸出: -1
解釋: 7 體積的可樂不能被平分.
注意事項
s <= 100
public class Solution {
/**
* @param s: the volume of cola
* @param n: the volume of the first cup
* @param m: the volume of the second cup
* @return: the minimum number of times to be inverted
*/
public int getMinTimes(int s, int n, int m) {
// Write your code here
if(s%2==1) return -1;
LinkedList<Integer> queue=new LinkedList<>();
int num=s*10000;
HashSet<Integer> set=new HashSet<>();
set.add(num);
queue.add(num);
int cnt=0;
while(queue.size()>0){
int len=queue.size();
cnt++;
while(len-->0){
int a=queue.poll();
int s1=a/10000;
int n1=(a/100)%100;
int m1=a%100;
// System.out.println("cnt:"+cnt+">>>"+a);
if(n1==s/2||m1==s/2) return cnt;
if(s1<s){
int b=10000*Math.min(s,s1+n1)+100*Math.max(0,n1-(s-s1))+m1;
if(!set.contains(b)){
queue.add(b);
set.add(b);
}
int b1=10000*Math.min(s,s1+m1)+100*n1+Math.max(0,m1-(s-s1));
if(!set.contains(b1)){
queue.add(b1);
set.add(b1);
}
}
if(n1<n){
int b=10000*Math.max(0,s1-(n-n1))+100*Math.min(n,s1+n1)+m1;
if(!set.contains(b)){
queue.add(b);
set.add(b);
}
int b1=10000*s1+100*Math.min(n,n1+m1)+Math.max(0,m1-(n-n1));
if(!set.contains(b1)){
queue.add(b1);
set.add(b1);
}
}
if(m1<m){
int b=10000*Math.max(0,s1-(m-m1))+100*n1+Math.min(m,m1+s1);
if(!set.contains(b)){
queue.add(b);
set.add(b);
}
int b1=10000*s1+100*Math.max(0,n1-(m-m1))+Math.min(m,m1+n1);
if(!set.contains(b1)){
queue.add(b1);
set.add(b1);
}
}
}
}
return -1;
}
}