[54]電容充電-位元組跳動2018秋
1.題目描述
有一臺用電容組成的計算器,其中每個電容元件都有一個最大容量值(正整數)。
對於單個電容,有如下操作指令:
指令1:放電操作-把該電容當前電量值清零
指令2:充電操作-把該電容當前電量補充到其最大容量值
對於兩個電容A和B,有如下操作指令:
指令3:轉移操作-從A中儘可能多的將電量轉移到B,轉移不會有電量損失,如果能夠充滿B的最大容量,那剩餘的電量仍然會留在A中
現在已知有兩個電容,其最大容量分別為a
和b
,其初始狀態都是電量值為0,希望通過一系列的操作可以使其中某個電容(無所謂哪一個)中的電量值等於c
(c
也是正整數),這一系列操作所用的最少指令條數記為M
,如果無論如何操作,都不可能完成,則定義此時M=0
。
顯然對於每一組確定的a
、b
、c
,一定會有一個M
與其對應。
- 輸入描述:
每組測試樣本的輸入格式為:
第一行是一個正整數N
從第二行開始,每行都是3個正整數依次組成一組a
、b
、c
,一共有N
組 - 輸出描述:
輸出為N
行,每行列印每一組的對應的M
- 資料範圍:
N
:0<N<100
a
、b
、c
:0
<a
、b
、c
<10^5
(50%)0
<a
、b
、c
<10^7
(30%)0
<a
、b
、c
<10^9
(20%) - 輸入示例:
2 3 4 2 2 3 4
- 輸出示例:
4 0
- 說明:
對於(3,4,2)
,最少只需要4個指令即可完成:
(設最大容量為3的是A號電容,另一個是B號電容)- 充電A轉移A->B
- 充電A轉移A->B
此時A中當前電量為2
,操作完成,所以輸出4
。
對於(2,3,4)
,顯然不可能完成,輸出0
。
2.題目解析
- 簡單情況
- 若
c>a
且c>b
,則顯然不可能完成,M
為0
。 - 若
c=a
或c=b
,則顯然一次操作可完成,M
為1
。
- 若
- 其他情況
示例條件- A容量
a=3
- B容量
b=4
- 目標電量
c=2
- A容量
一共有兩種方式
小容量的先充電,然後轉移到大容量
操作 | A電量(a=3) | B電量(b=4) |
---|---|---|
初始狀態 | 0 | 0 |
A充電 | 3 | 0 |
A轉移到B | 0 | 3 |
A充電 | 3 | 3 |
A轉移到B | 2 | 4 |
指令條數M=4
大容量的先充電,然後轉移到小容量
操作 | A電量(a=3) | B電量(b=4) |
---|---|---|
初始狀態 | 0 | 0 |
B充電 | 0 | 4 |
B轉移到A | 3 | 1 |
B放電 | 0 | 1 |
B轉移到A | 1 | 0 |
B充電 | 1 | 4 |
B轉移到A | 3 | 2 |
指令條數M=6
從小到大一定比從大到小指令少?
現在考慮剩餘情況,即c<Max(a,b)
且c≠Min(a,b)
(條件1)
將電容A、B看作一個整體,整體電容只有充電和放電兩種操作。其中充電使整體總電量增加,放電使整體總電量減少,則系統總電量可以達到的數值為ax+by
(a
、b
為整數,且ab<0
),其中x
、y
中為正的表示充電,為負的表示放電。因為條件1,所以a
、b
一定是一正一負,即ab<0
。
要使電量為c
,則要滿足等式ax+by=c
。根據裴蜀定理,等式可以滿足當且僅當gcd(a,b)|c
,即a
,b
的最大公約數也是c
的因子。
裴蜀/貝祖定理
若是整數,且,那麼對於任意的整數,都一定是的倍數,特別地,一定存在整數,使成立。
相反,若c mod gcd(a,b)≠0
,則電量不能達到c
,M
為0
。
現在假設gcd(a,b)|c
,即存在一正一負的整數x
,y
滿足等式ax+by=c
,不妨設x>0
,則整體電容的具體操作流程如下:
- 給電容A充電
- 電容A轉移到電容B
- 若電容B滿電,則其放空電量
- 如果電容A電量非空,則轉2
- 轉1重複執行整個過程,直到某時刻電容A或B中電量為
c
為止
先給容量大的充電(),還是先給容量小的充電()?
指令條數M
= 轉移次數 + 充電次數 + 放電次數
轉移次數 = 充電次數 + 放電次數?
其電容操作次數有如下兩種情況: 假設(b>a
)
- 若
c>a
(此時a<c<b
),則最終是B中先有c
的電量(A存不下),此時有x
次充電,−y
次放電,x−y
次轉移(因為B中先有c
的電量,每次A充電必然要轉移到B,每次B放電必然A非空由步驟4轉步驟2進行轉移操作),共2(x−y)
次操作。 - 若
c<a
(此時c<a
且c<b
),則最終是A中先有c
的電量(反證法:若B中先有,因為a
、b
都大於c
,所以必然是A轉移c
電量給空的B,此時A先有c
電量,矛盾),此時有x
次充電,−y−1
次放電(當A中有c
的電量時,必然是轉移給B後,A中剩餘c
的電量,此時B中滿電量不用放電也滿足題目要求,所以公式計算的放電次數需要減1
),x−y−1
次轉移(即實際需要充電次數x
加上實際需要放電次數−y−1
),共2(x−y−1)
次操作。
因此只需要最小化|x|+|y|
。若使用擴充套件歐幾里德演算法求出任意一組解(x,y)
,則等式ax+by=c
的全部整數解為:
找出其中距離0
最近的兩組解(x,y)
(一組x>0
,另一組y>0
),其中|x|+|y|
最小的一組就是達到最小運算元的解(x,y)
,根據上面分析可得到最小運算元。
參見[歐幾里得演算法]與[擴充套件歐幾里得演算法]
3.參考答案
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
// 擴充套件歐幾里得演算法
LL egcd(LL a, LL b, LL &x, LL &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
LL q = egcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
int main() {
int N = 0;
scanf("%d",&N);
while (N--) {
LL a, b, c, x, y;
scanf("%lld%lld%lld", &a,&b,&c);
int d = egcd(a, b, x, y); // 這裡是ax+by=d
// c大於A和B的容量,不能完成
// 根據裴蜀/貝祖定理,c不是gcd(a,b)的倍數,不能完成
if (c > a && c > b || c % d) {
printf("0\n");
continue;
}
// 剛好1步充滿A或者B
if (c == a || c == b) {
printf("1\n");
continue;
}
// 假設a>0
if (y > 0) swap(x, y), swap(a, b);
// 使ax + by = c (d是c的因子,即對上面式子ax + by = d兩邊同時乘以c / d)
x *= c / d; // 乘上c的約分
y *= c / d;
LL a2 = a / d; // a約分
LL b2 = b / d; // b約分
LL k = x / b2; // |x|+|y|最小的k?????
x -= k * b2; // 使這組(x, y)最接近0(x > 0時的整數解)
y += k * a2;
LL res;
if (c > a)
res = 2 * (x - y);
else
res = 2 * (x - y - 1);
// |x|+|y|最小????
x -= b2;
y += a2;
if (c > b)
res = min(res, 2 * (y - x));
else
res = min(res, 2 * (y - x - 1));
printf("%d\n",res);
}
return 0;
}
相關文章
- 位元組跳動揮劍亞馬遜電商?亞馬遜
- 位元組跳動上海招人
- 不要神化位元組跳動
- 位元組跳動,跳動的“遊戲夢”遊戲
- 2021 位元組跳動 ByteDance 秋招校招內推2NYX4JX
- 傳位元組跳動引入原阿里全球電競負責人,助力國際電競佈局阿里
- 攪局者,位元組跳動
- 位元組跳動“玩心”變重
- 再見了,位元組跳動
- 位元組跳動ios面經iOS
- 【位元熊充電棧】Azure OpenAI 特輯,滿電待充OpenAI
- 電子籤的背後江湖:騰訊、螞蟻、位元組跳動的較量
- 位元組跳動和TikTok內推
- 中信建投:孤獨的騰訊,跳動的位元組(位元組跳動篇-附下載)
- 手握15億月活,位元組跳動跳向何方?
- 位元組跳動近日申請多個“位元組遊戲”商標遊戲
- 位元組跳動如何做遊戲?遊戲
- 位元組跳動的「遊戲」法則遊戲
- 位元組跳動的技術架構架構
- 位元組跳動遊戲突圍戰遊戲
- 位元組跳動再啟音樂夢
- 年末重磅!【位元熊充電棧】Launch
- 位元組跳動財報:2023年位元組跳動銷售額1100億美元 增長30%
- 位元組跳動遊戲版圖再擴充套件 入股仙境傳說CP遊戲套件
- 位元組跳動web前端面試經歷Web前端面試
- 【上海】位元組跳動招聘研發工程師!!!工程師
- 位元組跳動的16款重度遊戲遊戲
- 位元組遊戲,跳動到哪兒了?遊戲
- 位元組跳動的遊戲大冒險遊戲
- 位元組跳動校招提前批開啟
- 位元組跳動怎麼都十萬人了?
- 位元組跳動虧12億美元?傳位元組跳動虧12億美元 擴張結果好壞參半
- 張一鳴退出位元組跳動卸任多家位元組關聯公司職務
- 張一鳴退出位元組跳動,卸任多家位元組關聯公司職務
- 位元組跳動視訊編解碼面經
- 位元組跳動VS騰訊:世紀之戰
- 誰在位元組跳動遊戲攪渾水?遊戲
- 位元組跳動拿到首個遊戲版號遊戲