日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 2142——扩展欧几里得

發布時間:2023/11/30 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 2142——扩展欧几里得 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目是很裸的擴展歐幾里得,但是對x,y有限制條件,要求所有x,y中abs(x)+abs(y)最小,在這個條件下要求abs(a* x)+abs(b* y)最小

顯然我們需要用擴展歐幾里得求得一組解,問題在于如何處理這組解以得到符合條件的值。

我是這樣處理的:最小的兩組解分別為x為最小非負整數和y為最小非負整數的情況。然后就過了,可是我想證明的時候證明了好久都沒有證明成功。在網上看其他人的題解找到一種靠譜的做法時我們令a>b(如果不是這樣就交換x,y,a,b),然后最小的和z=|x+b/dk|+|y-a/dk|,當后一項為正時,z隨k單調減小,當后一項為負時,z隨k單調增大。因此最小值在y-a/d*k=0的附近,一般應該是有兩個值,比較一下。

至于為什么我的想法正確我還得再想想。不過有個小經驗就是在處理出x后不要再去求k什么的再去求y,可以直接將y帶入方程得到y的值。

#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #include<ctime> #include<climits> #include<queue> #include<vector> #include<set> #include<map> using namespace std;typedef long long ll; const int INF=0x3f3f3f3f; const int MAXN=1e5+5;void ex_gcd(ll a,ll b,ll& d,ll& x,ll& y) {if(!b) {d=a; x=1; y=0;}else {ex_gcd(b,a%b,d,y,x); y-=(a/b)*x;} }ll a,b,c;ll Abs(int x) {return x<0?-x:x; }int main() {while(~scanf("%lld%lld%lld",&a,&b,&c)){ll x,y,d,k1,k2,a1,b1,k,x1,x2,y1,y2;if(!a && !b && !c) break;ex_gcd(a,b,d,x,y); a1=a/d; b1=b/d;x=c/d*x; y=c/d*y;//printf("%lld %lld\n",x,y);x1=(x%b1+b1)%b1; y1=Abs((c-a*x1)/b);y2=(y%a1+a1)%a1; x2=Abs((c-b*y2)/a);//printf("%lld %lld\n",x1,y1);//printf("%lld %lld\n",x2,y2);if(x1+y1<y2+x2){printf("%lld %lld\n",x1,y1);}else if(x1+y1>y2+x2){printf("%lld %lld\n",x2,y2);}else{ll c1=a*x1+b*y1; ll c2=a*x2+b*y2;if(c1<c2){printf("%lld %lld\n",x1,y1);}else{printf("%lld %lld\n",x2,y2);}}}return 0; }

總結

以上是生活随笔為你收集整理的POJ 2142——扩展欧几里得的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。