关于ax+by=c的解x,y的min(|x|+|y|)值问题

  首先我们移动一下项,并强行让a>b。

  然后我们可以画出这样一个图像

  我们发现,在线段l与x轴交点处的下方,x,y的绝度值是递增的,所以我们不考虑那个最小点在下端。

  之后我们发现在点的上端,因为斜率小于-1,x的减少远没有y加的快,所以我们知道极点在l与x轴的交汇处。

  但是该点不一定是整点啊。。

  所以我们只要找到它上面和下面最近的两个整点即可。

  所以我们求ax+by=c最小的正整数解y即可,之后调出x,然后y减去a,再求x,比较两次min(|x|+|y|),就可以得出答案了。

  当然如果第一次求出来的y=0,答案就是它了。。

  

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5
 6 #define ll long long
 7
 8 using namespace std;
 9
10 ll gcd(ll a,ll b)
11 {
12     return b==0?a:gcd(b,a%b);
13 }
14
15 ll x,y;
16
17 void exgcd(ll n,ll m)
18 {
19     if(m==0){x=1,y=0;return;}
20     exgcd(m,n%m);ll t=x;
21     x=y;y=t-n/m*y;
22 }
23
24 int main()
25 {
26     ll a,b,d;
27     scanf("%lld%lld",&a,&b);
28     ll gd=gcd(a,b);
29     a/=gd,b/=gd;
30     exgcd(a,b);
31     while(~scanf("%lld",&d))
32     {
33         if(d%gd){printf("BeiJu!\n");continue;}
34         d/=gd;
35         ll ans1=(y*d%a+a)%a,ans;
36         ans=abs(ans1)+abs((d-ans1*b)/a);
37         if(!ans1){printf("%lld\n",ans);return 0;}
38         ans1-=a;
39         ans=min(ans,abs(ans1)+abs((d-ans1*b)/a));
40         printf("%lld\n",ans);
41     }
42     return 0;
43 }

  代码略丑。。题目给出a,b,给出一堆c,求min(|x|+|y|).

时间: 2024-11-05 12:08:23

关于ax+by=c的解x,y的min(|x|+|y|)值问题的相关文章

Solve Equation gcd(x,y)=gcd(x+y,lcm(x,y)) gcd(x,y)=1 =&gt; gcd(x*y,x+y)=1

/** 题目:Solve Equation 链接:http://acm.hnust.edu.cn/JudgeOnline/problem.php?id=1643 //最终来源neu oj 2014新生选拔赛题 题意:给定两个数的和以及他们的最小公倍数,求这两个数. 思路: x+y=A lcm(x,y)=B => x*y/gcd(x,y)=B 要把这两个公式联立,那么必须消掉gcd: 设:d = gcd(x,y), x = kx*d, y = ky*d; kx与ky互质: x+y=A => d(

y=x^2 vs y=x^(1/2)

[y=x^2 vs y=x^(1/2)] y=x^2,基础函数,废话不多说. y=x^(1/2),指数变成了上式的倒数.x^(1/2)即是,√x.但函数图像会是什么样呢?可以把y=x^(1/2),转变成y^2 = x.这样之后,发现与上式形式一样,只是把x轴.y轴颠倒了.所以将上图X.Y轴对调一下即可得y=x^(1/2)图像. 发现Y只有大于0的部分,因为根确定符号必须大于0.为了得到真正的旋转图像,将函数改一下即可.|y|=x^(1/2). 可以发现,此2等式关于y=x对称.

MySQL四舍五入函数ROUND(x)、ROUND(x,y)和TRUNCATE(x,y)

MySQL四舍五入函数ROUND(x) ROUND(x)函数返回最接近于参数x的整数,对x值进行四舍五入. 实例: 使用ROUND(x)函数对操作数进行四舍五入操作.SQL语句如下: mysql>SELECT ROUND(-2.34),ROUND(-4.56),ROUND(2.34),ROUND(4.56); ROUND(x)函数的执行结果如下图所示: 上图中代码执行的结果显示,进行四舍五入处理以后,只保留了各个值的整数部分. MySQL四舍五入函数ROUND(x,y) ROUND(x,y)函数

x+=y与x=x+y有什么区别?

一般情况下,x+=y与x=x+y输出结果是等价的,因此两种写法是可以通用的,但是在某些临界值选用x+=y更加合适,比如: short n=3; n+=1;//编译通过 n=n+1;//编译失败 上述例子中,n=n+1等号右侧计算结果为int类型,而左侧变量类型依然是short类型,违反了自动转换规则,需要执行强制转换.而n+=1语句编译通过是因为"+="运算符在Java环境中会自动根据接收变量的类型进行类型强制转换. 因此,x+=y 等价于 x=x+y 与 强制类型转换操作 类似运算符

异或交换两个数;实现pow(int x, int y) ,即x的y次方

问题1:异或交换两个数 假设x=2:y=3,我们的目标是(没有蛀牙!!)交换x,y的值: 利用异或的特殊性:x^x=0 即两个相同数字异或后值为0: 解决: 令x=x^y=2^3 令y=x^y=x^y^y=2^3^3=2(此时x=x^y) 令x=x^y=x^y^2=2^3^2=3(此时x=x^y:y=2) 问题2:实现pow(int x, int y) ,即x的y次方 x的y次方就是有y个x连续乘机,代码如下: #include <stdio.h> #include <stdlib.h&

yum -y upgrade 和 yum -y update 区别

分别测试yum -y upgrade和yum -y update 升级前 系统版本: CentOS5.5 内核版本: 2.6.18-194.el5 升级前做过简单配置文件修改 yum -y upgrade 升级后 系统版本: centos5.7 内核版本: 2.6.18-194.el5 系统和软件配置不做修改 yum -y update 升级后 系统版本: centos5.7 内核版本: 2.6.18-238.el5 系统和软件配置文件更新 结论: yum -y update 升级所有包,改变软

poj 1915 双向 BFS 利用数组 a[x][y] = a[cp.x][cp.y] + 1; b[x][y] = b[cp.x][cp.y] + 1;保留步数

#include<iostream>#include<queue> using namespace std; struct point{    int x, y;};point bufa[8] ={    {-2, 1}, {-1, 2}, {1, 2}, {2, 1},    {2, -1}, {1, -2}, {-1, -2}, {-2, -1}}; int n, a[305][305], b[305][305]; int rule(int x,int y)//判断是否符合棋盘

关于N阶常系数差分方程和微分方程的对比易误点(d &#39; y(t)/dt 对应 y[n - 1] ? )

Linear Constant-coefficient difference equations 这里有个容易"让人困惑"的地方,仔细观察两个方程,加上这里书上说了一句"1.109式(图中上面的公式),对应的离散时间方程是下面的方程" 发现会有一种感觉,"既然是对应的,那么这里d ' y(t)/dt 岂不是对应 y[n - 1]  (当k = 1时)" 正是这样,我就陷入了深深的困惑... 会觉得"怎么连续领域内的一阶导数等于离散领域内

【c语言】有一函数:x &lt; 0 ,y = -1;x = 0,y = 0;x &gt; 0,y = 1,编程输入一个x值,要求输出对应的y

// 有一函数:x < 0 ,y = -1;x = 0,y = 0;x > 0,y = 1,编程输入一个x值,要求输出对应的y #include <stdio.h> int main() { int x,y; printf("请输入x:"); scanf("%d",&x); if(x > 0) y = 1; else if(x < 0) y = -1; else y = 0; printf("对应的y值是:%d\