POJ 2142 TheBalance 模线性方程求解
2015-01-17 15:33
363 查看
题目大意:
就是将两种砝码左右摆放,能够在物品放置在天平上时保持平衡
很容易得到 ax + by = t的模线性方程
按题目要求,希望首先满足 |x| + |y| 最小 , 如果有多种情况,再满足所有砝码质量最小,也就是a|x| + b|y|最小
x = x0 + b/g * k
y = y0 - a/g * k
这里可以通过画一个2维坐标图进行观察 x , y 对于k的直线,我假定 b > a ,初始如果 a>b就交换两者数据,记得最后答案交换回来
因为a,b为砝码重量都大于0
所以x是递增直线,y是递减直线
因为假设b > a了,所以x的上升趋势必然大于y的下降趋势
所以只有在x = 0的左右两个点是满足最小的情况的 , 用xx[2] , yy[2]记录这两个点,然后进行比较即可
/*
当然不交换a , b 也可以, 那就得在 a > b 的条件下多保存两组数据,此时是在y = 0 的左右两个点
*/
就是将两种砝码左右摆放,能够在物品放置在天平上时保持平衡
很容易得到 ax + by = t的模线性方程
按题目要求,希望首先满足 |x| + |y| 最小 , 如果有多种情况,再满足所有砝码质量最小,也就是a|x| + b|y|最小
x = x0 + b/g * k
y = y0 - a/g * k
这里可以通过画一个2维坐标图进行观察 x , y 对于k的直线,我假定 b > a ,初始如果 a>b就交换两者数据,记得最后答案交换回来
因为a,b为砝码重量都大于0
所以x是递增直线,y是递减直线
因为假设b > a了,所以x的上升趋势必然大于y的下降趋势
所以只有在x = 0的左右两个点是满足最小的情况的 , 用xx[2] , yy[2]记录这两个点,然后进行比较即可
/*
当然不交换a , b 也可以, 那就得在 a > b 的条件下多保存两组数据,此时是在y = 0 的左右两个点
*/
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int ex_gcd(int a , int &x , int b , int &y) { if(b == 0){ x = 1 , y = 0; return a; } int ans = ex_gcd(b , x , a%b , y); int t = x; x = y , y = t - a/b*y; return ans; } void my_swap(int &a , int &b) { int t = a; a = b , b = t; } int my_abs(int a) { return a>=0?a:-a; } int main() { // freopen("a.in" , "r" , stdin); int a , b , w; while(scanf("%d%d%d" , &a , &b , &w) , a){ int x , y; bool flag = false; if(b < a){ my_swap(a , b); flag = true; } int g = ex_gcd(a , x , b , y); int k = w/g; x = k*x , y = k*y; a /= g , b /= g; int xx[2] , yy[2]; if(x >= 0){ xx[0] = x - x/b*b; xx[1] = xx[0] - b; yy[0] = y + x/b*a; yy[1] = yy[0] + a; }else{ xx[0] = x - x/b*b+b; xx[1] = xx[0] - b; yy[0] = y + x/b*a - a; yy[1] = yy[0] + a; } int ansx , ansy; if(my_abs(xx[0]) + my_abs(yy[0]) == my_abs(xx[1]) + my_abs(yy[1])){ if(my_abs(xx[0])*a + my_abs(yy[0])*b < my_abs(xx[1])*a + my_abs(yy[1])*b) ansx = my_abs(xx[0]) , ansy = my_abs(yy[0]); else ansx = my_abs(xx[1]) , ansy = my_abs(yy[1]); } else{ if(my_abs(xx[0]) + my_abs(yy[0]) < my_abs(xx[1]) + my_abs(yy[1])) ansx = my_abs(xx[0]) , ansy = my_abs(yy[0]); else ansx = my_abs(xx[1]) , ansy = my_abs(yy[1]); } if(flag) my_swap(ansx , ansy); printf("%d %d\n" , ansx , ansy); } return 0; }
相关文章推荐
- POJ - 2115 C Looooops(扩展欧几里德求解模线性方程(线性同余方程))
- POJ 2115 简单的模线性方程求解
- POJ 2115 C Looooops(扩展欧几里德 + 求解模线性方程)
- [ACM] POJ 2115 C Looooops (扩展欧几里得求解模线性方程)
- POJ 2142 The Balance 解题报告(模线性方程)
- POJ2115——C Looooops(扩展欧几里德+求解模线性方程)
- POJ_2142_The Balance(模线性方程)
- POJ 1061 青蛙的约会(扩展GCD求模线性方程)
- POJ 2417 Discrete Logging (求解模方程a^x≡b(mod n))
- poj 2417 Discrete Logging 求解模方程a^x=b(mod n),n为素数+模板题(baby_step giant_step)
- 数论基础1012 POJ 1061 模线性方程
- poj 2065 SETI 高斯消元解模线性方程
- 同余方程(线性模方程)求解青蛙约会问题
- POJ 2115 C Looooops 解题报告(模线性方程)
- POJ 2891 Strange Way to Express Integers 【中国剩余定理线性模方程合并(模板)】
- poj 2891 一般模线性方程
- POJ 2891 多元同余线性方程
- 【模线性方程 && 扩展欧几里德】POJ - 2115 C Looooops
- [poj 2115]C Looooops[扩展欧几里德][模线性方程]
- Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)