标签:gcd
题目链接:点击打开链接
题意:给出x, k 求 方程 p*floor(x/k)+q*ceil(x/k)=x的一个解。floor()为向上取整,ceil()为向下取整。
赤裸裸的扩展gcd,题目中没说无解的情况,应该是默认 x%gcd(floor(x/k),ceil(x/k))==0
对于扩展gcd,ax+by=d ① ,当d为g=gcd(a,b)的倍数时,方程①有解,转化为求 ax+by=g ②的解,假设求出来方程②的解为 (x0,y0)
方程②左右同乘 d/g,得 a*(x0*d/g)+b*(y0*d/g)=g*d/g,所以方程①的解为 (x0*d/g,y0*d/g)
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define maxn 1002 #define _ll __int64 #define ll long long #define INF 0x3f3f3f3f #define Mod 10000007 #define pp pair<int,int> #define ull unsigned long long using namespace std; ll x,k; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } ll 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-=x*(a/b);} } void solve() { ll a=floor((double)x/(double)k); ll b=ceil((double)x/(double)k); ll g=gcd(a,b); ll d=g,tx,ty;a/=g;b/=g; ex_gcd(a,b,d,tx,ty); printf("%lld %lld\n",tx*x/g,ty*x/g); } int main() { int T;scanf("%d",&T); while(T--){ scanf("%lld %lld",&x,&k); solve(); } return 0; }
Uva 10673-Play with Floor and Ceil(扩展欧几里得)
标签:gcd
原文地址:http://blog.csdn.net/qq_16255321/article/details/42062587