POJ.2142 The Balance (拓展欧几里得)

题意分析

现有2种质量为a克与b克的砝码,求最少 分别用多少个(同时总质量也最小)砝码,使得能称出c克的物品。

设两种砝码分别有x个与y个,那么有ax+by=c。可用拓展欧几里得求解。

若x与y均为正数,说明在天平的同一侧,否则在不同册。

需要注意的是,求出的x与y仅为一组特解,此时需要求|x| + |y| 的最小值。根据:

可得

显然这是不好求的,但我们不妨设a>b,根据斜率关系,不难作图。

可以看出,最小值在t2附近取得,枚举附近值计算,取最小即可。

代码总览

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
typedef int ll;
void exgcd(ll a, ll b, ll& d, ll& x, ll &y)
{
if(!b){
d = a,x = 1,y = 0;
}else{
exgcd(b, a % b, d, y, x);
y -= x * (a / b);
}
}
void cal(ll a, ll b,ll c)
{
ll gcd,x,y;
bool isswap = false;
if(b>a){
swap(a,b);
isswap = true;
}
exgcd(a,b,gcd,x,y);
x = x *(c/gcd);
y = y *(c/gcd);
int k1 = b /gcd ;
int k2 = a /gcd ;
int t = y * gcd / a;
int min = fabs(x)+ fabs(y),num1 = fabs(x),num2 = fabs(y);
for(int i = -10; i<=10;++i){
int temp = t+i;
if(min>fabs(x+k1*temp) + fabs(y-k2*temp)){
min = fabs(x+k1*temp) + fabs(y-k2*temp);
num1 = fabs(x+k1*temp);
num2 = fabs(y-k2*temp);
}
}
if(isswap) swap(num1,num2);
printf("%d %d\n",num1,num2);
}
int main()
{
//freopen("in.txt","r",stdin);
ll a,b,c;
while(scanf("%d %d %d",&a,&b,&c)){
if(a == 0 && b == 0 && c == 0) break;
cal(a,b,c);
}
return 0;
}

POJ.2142 The Balance (拓展欧几里得)的更多相关文章

  1. POJ 2142 - The Balance [ 扩展欧几里得 ]

    题意: 给定 a b n找到满足ax+by=n 的x,y 令|x|+|y|最小(等时令a|x|+b|y|最小) 分析: 算法一定是扩展欧几里得. 最小的时候一定是 x 是最小正值 或者 y 是最小正值 ...

  2. POJ 2142:The Balance_扩展欧几里得(多组解)

    先做出两个函数的图像,然后求|x|+|y|的最小值.|x|+|y|=|x0+b/d *t |+|y0-a/d *t| 这个关于t的函数的最小值应该在t零点附近(在斜率大的那条折线的零点附近,可以观察出 ...

  3. poj 1061 青蛙的约会 拓展欧几里得模板

    // poj 1061 青蛙的约会 拓展欧几里得模板 // 注意进行exgcd时,保证a,b是正数,最后的答案如果是负数,要加上一个膜 #include <cstdio> #include ...

  4. POJ.1006 Biorhythms (拓展欧几里得+中国剩余定理)

    POJ.1006 Biorhythms (拓展欧几里得+中国剩余定理) 题意分析 不妨设日期为x,根据题意可以列出日期上的方程: 化简可得: 根据中国剩余定理求解即可. 代码总览 #include & ...

  5. POJ.1061 青蛙的约会 (拓展欧几里得)

    POJ.1061 青蛙的约会 (拓展欧几里得) 题意分析 我们设两只小青蛙每只都跳了X次,由于他们相遇,可以得出他们同余,则有: 代码总览 #include <iostream> #inc ...

  6. poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】

    POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...

  7. POJ 2891 Strange Way to Express Integers(拓展欧几里得)

    Description Elina is reading a book written by Rujia Liu, which introduces a strange way to express ...

  8. poj 1061 青蛙的约会+拓展欧几里得+题解

    青蛙的约会+拓展欧几里得+题解 纵有疾风起 题意 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出 ...

  9. NOIP2012拓展欧几里得

    拉板题,,,不说话 我之前是不是说过数据结构很烦,,,我想收回,,,今天开始的数论还要恶心,一早上听得头都晕了 先来一发欧几里得拓展裸 #include <cstdio> void gcd ...

随机推荐

  1. Qt 计算两个日前间隔天数

    某一个大神写的 改写了一点 请无视注释 //时间计算法则 /********************************************************************** ...

  2. 【system.file】使用说明

    对象:system.file 说明:提供一系列针对文件操作的方法. 注意:参数中的filePath 均为相对网站根目录路径 目录: 方法 返回 说明 system.file.exists(filePa ...

  3. Java并发基础--volatile关键字

    一.java内存模型 1.java内存模型 程序运行过程中的临时数据是存放在主存(物理内存)中,但是现代计算机CPU的运算能力和速度非常的高效,从内存中读取和写入数据的速度跟不上CPU的处理速度,在这 ...

  4. stm32之SPI通信协议

    SPI (Serial Peripheral interface),顾名思义就是串行外围设备接口.SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为P ...

  5. Python面向对象-类成员

    类的成员可以分为三大类:字段.方法和属性: 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在 ...

  6. ACM 第十七天

    暑期热身赛 BAPC 2014 The 2014 Benelux Algorithm Programming Contest 题目网址:https://odzkskevi.qnssl.com/3655 ...

  7. 【week4】课堂Scrum站立会议

    项目:连连看游戏 小组名称:天天向上(旁听) 小组成员:张政 张金生 李权 武致远 已完成任务 1.本项目采用c#. 2. 初步界面. 形成一个windows下的游戏界面,每个需要消除的方块是一个bu ...

  8. 【Docker 命令】- start/stop/restart命令

    docker start:启动一个或多少已经被停止的容器 docker stop:停止一个运行中的容器 docker restart :重启容器 语法: docker start [OPTIONS] ...

  9. 封装字符串的Format操作

    相信即使再讨厌MFC的朋友也不会把厌恶牵扯到CString类上,而且CString现在也提升为ATL和MFC的共享类.用CString类,当然不能忘记它的Format方法,其用于格式化字符串.示例操作 ...

  10. [C/C++] 原码、反码、补码问题

    正确答案:D 解析: C语言中变量以补码形式存放在内存中,正数的补码与原码相同,负数求补码方式为(符号位不变,其余各位取反,最后末尾加1): 32位机器:int 32位,short 16位.  x = ...