zoukankan      html  css  js  c++  java
  • POJ 2142 TheBalance 模线性方程求解

    题目大意:

    就是将两种砝码左右摆放,能够在物品放置在天平上时保持平衡

    很容易得到 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 的左右两个点

    */

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 
     6 int ex_gcd(int a , int &x , int b , int &y)
     7 {
     8     if(b == 0){
     9         x = 1 , y = 0;
    10         return a;
    11     }
    12     int ans = ex_gcd(b , x , a%b , y);
    13     int t = x;
    14     x = y , y = t - a/b*y;
    15     return ans;
    16 }
    17 
    18 void my_swap(int &a , int &b)
    19 {
    20     int t = a;
    21     a = b , b = t;
    22 }
    23 
    24 int my_abs(int a)
    25 {
    26     return a>=0?a:-a;
    27 }
    28 
    29 int main()
    30 {
    31    // freopen("a.in" , "r" , stdin);
    32     int a , b , w;
    33     while(scanf("%d%d%d" , &a , &b , &w) , a){
    34         int x , y;
    35         bool flag = false;
    36         if(b < a){
    37             my_swap(a , b);
    38             flag = true;
    39         }
    40 
    41         int g = ex_gcd(a , x , b , y);
    42         int k = w/g;
    43         x = k*x , y = k*y;
    44         a /= g , b /= g;
    45         int xx[2] , yy[2];
    46         if(x >= 0){
    47             xx[0] = x - x/b*b;
    48             xx[1] = xx[0] - b;
    49             yy[0] = y + x/b*a;
    50             yy[1] = yy[0] + a;
    51         }else{
    52             xx[0] = x - x/b*b+b;
    53             xx[1] = xx[0] - b;
    54             yy[0] = y + x/b*a - a;
    55             yy[1] = yy[0] + a;
    56         }
    57         int ansx , ansy;
    58         if(my_abs(xx[0]) + my_abs(yy[0]) == my_abs(xx[1]) + my_abs(yy[1])){
    59             if(my_abs(xx[0])*a + my_abs(yy[0])*b < my_abs(xx[1])*a + my_abs(yy[1])*b)
    60                 ansx = my_abs(xx[0]) , ansy = my_abs(yy[0]);
    61             else
    62                 ansx = my_abs(xx[1]) , ansy = my_abs(yy[1]);
    63         }
    64         else{
    65             if(my_abs(xx[0]) + my_abs(yy[0]) < my_abs(xx[1]) + my_abs(yy[1]))
    66                 ansx = my_abs(xx[0]) , ansy = my_abs(yy[0]);
    67             else
    68                 ansx = my_abs(xx[1]) , ansy = my_abs(yy[1]);
    69         }
    70         if(flag)
    71             my_swap(ansx , ansy);
    72         printf("%d %d
    " , ansx , ansy);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    CyclicBarrier与CountDownLatch区别
    导入搜狗实验室新闻语料库
    安装ik分词插件
    分页显示时传递页码的方法
    elasticsearch安装步骤
    linux查看端口占用情况
    Python:文件的读取、创建、追加、删除、清空
    R语言-选择样本数量
    不符合正态分布的配对数据也有自己的统计方法。
    python时间处理
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4230512.html
Copyright © 2011-2022 走看看