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. pygame安装【在pycharm的IDE project下】

    pygame安装[在pycharm的IDE project下] 首先更新电脑的pip.exe[命令行下面] 然后进入IDE project ——>setting 中查找是否安装pygame 我的 ...

  2. Linux文件系统简介和软链接和硬链接的区别

    Linux有着极其丰富的文件系统,大体可分为如下几类: 网络文件系统:如nfs.cifs等: 磁盘文件系统:如ext3.ext4等: 特殊文件系统:如prco.sysfs.ramfs.tmpfs等: ...

  3. 【转】: 探索Lua5.2内部实现:虚拟机指令(2) MOVE & LOAD

    name args desc OP_MOVE A B R(A) := R(B) OP_MOVE用来将寄存器B中的值拷贝到寄存器A中.由于Lua是register based vm,大部分的指令都是直接 ...

  4. Java算法2

    实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 分析:若从前向后遍历的话,那Happy后面 ...

  5. LeetCode - 167. Two Sum II - Input array is sorted - O(n) - ( C++ ) - 解题报告

    1.题目大意 Given an array of integers that is already sorted in ascending order, find two numbers such t ...

  6. Some good articles

    https://alligator.io/vuejs/introduction-render-functions/ https://alligator.io/vuejs/vue-jwt-pattern ...

  7. Linux系统inotify工具安装配置

    inotify主要功能 Inotify 是一个 Linux特性,它监控文件系统操作,比如读取.写入和创建.Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多.学习如何将 ...

  8. 2018-9-25kanboard安装及使用

    2018-9-25kanboard安装及使用 教程 小书匠  欢迎走进zozo的学习之旅. 简介 运行官方docker容器 使用kanboard 简介 Kanboard的安装提供了两种方式一种是直接安 ...

  9. popen()与system()

    一.popen() 用途:执行shell命令(并读取其输出或向其发送一些输入) 特点:通过管道来与shell命令进行通信 二.system()

  10. 第三次寒假作业 sketch 了解

    什么是sketch? sketch 是一种基于散列的数据结构,可以在高速网络环境中,实时地存储流量特征信息,只占用较小的空间资源,并且具备在理论上可证明的估计精度与内存的平衡特性. 通过设置散列函数, ...