題目描述
前兩天,14級計算機巨神真感情學長的一道題被×了!!!被×了!!!被×了!!!
真感情學長灰常的不開心,所以就去找我喝酒,他帶了一桶S ml的82年啦飛和兩個容量分別爲N ml和M ml的杯子,因爲他要不醉不歸所以帶了非常大的兩個杯子使得兩人一人一杯就可以喝完這一桶酒,也就是說N+M=S,但是陪他喝酒的我不想藉此機會暴露出兩人酒量高低,所以給他提了一個要求——我們兩個人喝的酒必須一樣多,這就讓真感情很尷尬了,所以他請來他的學弟學妹,也就是你們,幫他解決這個問題,如果誰能解決他就罩着你,以後你就可以在計算機學院橫着走了,當然本人爲了考驗真感情的水平,要求他用最少的操作把這桶酒分成兩半(每次操作就是從一個容器向另一個容器倒酒,容器沒有刻度),快努力幫助你們的大神學長吧!
輸入
多組用例,每組用例佔一行包括三個正整數S,N,M分別表示一個桶和兩個杯子的容量(N,M<2^31,S=N+M)
以EOF結束輸入
輸出
對於每組用例,輸出一個整數爲將該桶酒平分的最少操作數,如果無法平分,那麼就輸出“ZGQ drinks off !”
樣例輸入
2 1 1
樣例輸出
1
測試輸入 | 期待的輸出 | 時間限制 | 內存限制 | 額外進程 | |
---|---|---|---|---|---|
測試用例 1 |
以文本方式顯示
|
以文本方式顯示
|
2秒 | 64M | 0 |
測試用例 2 |
以文本方式顯示
|
以文本方式顯示
|
2秒 | 64M | 0 |
得到通解之後,就是該求答案了。易知肯定一個大於0一個小於0,所以不妨設x>0,y<0,當操作次數最小的時候就是倒入第一個x次,倒入第二個|y|次,但是由於瓶子容積有限,所以倒進倒出操作都是通過大瓶子來解決的,一次倒進操作後爲了繼續使用小瓶子還要將小瓶子中可樂倒回大瓶子中,倒出操作同理,所以總操作次數是2*(x+y)次,但是要注意最後的(a+b)/2是要放回大瓶子裏而不是再倒回,所以乘2之後再減1,所以答案就是2*(|x|+|y|)-1,那麼|x|+|y|該怎麼求呢?
(截自強神博客)
即答案就是a+b-1.
ps:數據要用long long
AC代碼:
#include<stdio.h>
#include<math.h>
long long gcd(long long a, long long b)//求最大公約數
{
long long int c;
while (b != 0) /* 餘數不爲0,繼續相除,直到餘數爲0 */
{
c = a%b;
a = b;
b = c;
}
return a;
}
int main()
{
long long int s, n, m;
while (scanf("%lld%lld%lld", &s, &n, &m) != EOF)
{
long long int a = n, b = m, c = s / 2;//求ax+by=(a+b)/2
long long int g = gcd(a, b);
if (c%g != 0 || s % 2 == 1)
printf("ZGQ drinks off !\n");
else
{
a = a / g;
b = b / g;
c = c / g;
long long int x = (1 - b) / 2, y = (1 + a) / 2;//此處x和y是兩特解,通解爲x+k*b,y-k*a
x = x < 0 ? -x : x;
y = y < 0 ? -y : y;
long long int ans = (x+y) * 2;
printf("%lld\n", ans-1);
}
}
return 0;
}