1. 程式人生 > >POJ2142 The Balance

POJ2142 The Balance

即使 正整數 queue printf 一個 print poj string define

傳送門

這道題是一道相當不錯的不定方程的題!

題目大意是要我們用若幹個兩種給定質量的砝碼稱出給定質量的物品,其中滿足使用砝碼總數最小,如果有多組解輸出砝碼質量最小的一組解。

其實轉化一下我們還是要求ax+by=c的一組解……

這個當然很好求,之後既然要求砝碼總數最小,我們只要讓x或者y最小即可,然後比較兩者總數大小。最小的正整數解很好求,這樣的話對應的另一個值就是固定的(如果是負數要取相反數,相當於放在天平不同位置)

至於為什麽取最小,因為不定方程的通解是有公式的,如果我們不取最小的正整數解,那麽另一種砝碼必然比原來更多,不可能更優(即使是負數也會取相反數)

然後其實我個人認為好像不用管質量最小……反正我沒管就過了,也許是數據有點水。

看一下代碼。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<queue>
#define pb push_back
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define
enter putchar(‘\n‘) using namespace std; typedef long long ll; const int M = 40005; const int N = 2000005; const int INF = 1000000009; const ll mod = 51123987; ll read() { ll ans = 0,op = 1; char ch = getchar(); while(ch < 0 || ch > 9) { if(ch == -) op = -1; ch = getchar(); }
while(ch >= 0 && ch <= 9) { ans *= 10; ans += ch - 0; ch = getchar(); } return ans * op; } ll a,b,c,x,y,G,d,kx,ky,sx,sy; ll gcd(ll a,ll b) { return (!b) ? a : gcd(b,a%b); } ll exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x = 1,y = 0; return a; } d = exgcd(b,a%b,y,x); y -= a / b * x; return d; } int main() { while(1) { a = read(),b = read(),c = read(); if(!a && !b && !c) break; G = gcd(a,b); a /= G,b /= G,c /= G; exgcd(a,b,x,y); kx = (x + b) % b,kx *= c,kx %= b; ky = (c - a * kx) / b; if(ky < 0) ky = -ky; sy = (y + a) % a,sy *= c,sy %= a; sx = (c - b * sy) / a; if(sx < 0) sx = -sx; if(sx + sy < kx + ky) printf("%lld %lld\n",sx,sy); else printf("%lld %lld\n",kx,ky); } return 0; }

POJ2142 The Balance