zoukankan      html  css  js  c++  java
  • poj 2142 扩展欧几里得解ax+by=c

     原题实际上就是求方程a*x+b*y=d的一个特解,要求这个特解满足|x|+|y|最小

    套模式+一点YY就行了

    总结一下这类问题的解法:

    对于方程ax+by=c

    设tm=gcd(a,b)

    先用扩展欧几里得求出方程ax+by=tm的解x0、y0

    然后有a*x0+b*y0=tm

    令x1=x0*(c/tm),y1=y0*(c/tm)

    则a*x1+b*y1=c

    x1、y1即原方程的一个特解

    这个方程的通解:xi=x1+k*(b/m),yi=y1-k*(a/m)

    另:如果要求yi的最小非负解?令r=a/tm,则解y2=(y1%r+r)%r

    针对本题,求出x1、y1后可以YY一下:

    (1):若x1>0,y1>0,

       1.y1-=(a/m),直到y1<0

       2.y1+=(a/m),直到x1<0

    (2):若x1<0,y1>0

         y1-=(a/m),直到y1<0

    易知最优解一定出现在这一咕噜里头,操作的同时更新最优答案即可。

     1 #include <iostream>
     2 #include <cmath>
     3 using namespace std;
     4 
     5 int gcd(int a,int b){
     6         if (b==0) return a;
     7         return gcd(b,a%b);
     8     }
     9 
    10 int extgcd(int a,int b,int& x,int& y){
    11         int d=a;
    12         if (b!=0){
    13             d=extgcd(b,a%b,y,x);
    14             y-=(a/b)*x;
    15         }else{
    16             x=1;y=0;
    17         }
    18         return d;
    19     }
    20 
    21 int main()
    22 {
    23     int a,b,d,ax,ay,ans;
    24     while (cin>>a>>b>>d)
    25     {
    26         if (a==0 && b==0 && d==0)   break;
    27         else
    28         {
    29             int x,y;
    30             int tm=extgcd(a,b,x,y);
    31             int x1=x*(d/tm),y1=y*(d/tm);
    32             int ra=a/tm,rb=b/tm;
    33             y1=(y1%ra+ra)%ra;
    34             x1=(d-y1*b)/a;
    35             int x2=x1,y2=y1;
    36             ans=abs(x2)+abs(y2);
    37             ax=x2;      ay=y2;
    38             if (x2<0)
    39             {
    40                 while (y2>0)
    41                 {
    42                     y2-=ra; x2+=rb;
    43                     if ((abs(y2)+abs(x2))<ans)
    44                     {
    45                         ans=abs(y2)+abs(x2);
    46                         ax=x2;  ay=y2;
    47                     }
    48                 }
    49             }
    50             else if (x2>0)
    51             {
    52                 while (y2>0)
    53                 {
    54                     y2-=ra; x2+=rb;
    55                     if ((abs(y2)+abs(x2))<ans)
    56                     {
    57                         ans=abs(y2)+abs(x2);
    58                         ax=x2;  ay=y2;
    59                     }
    60                 }
    61                 x2=x1;  y2=y1;
    62                 while (x2>0)
    63                 {
    64                     y2+=ra; x2-=rb;
    65                     if ((abs(y2)+abs(x2))<ans)
    66                     {
    67                         ans=abs(y2)+abs(x2);
    68                         ax=x2;  ay=y2;
    69                     }
    70                 }
    71             }
    72             cout<<abs(ax)<<" "<<abs(ay)<<endl;
    73         }
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    SuperMap开发入门1——资源下载
    去除Win10快捷图标小箭头
    MongoTemplate 分组分页复合条件查询
    mongo db 去除 _class 字段
    MongoDb 快速翻页方法
    mysql select limit 大数据量查询 性能终极提升方法
    MongoDB 数据自动同步到 ElasticSearch
    用 mongodb + elasticsearch 实现中文检索
    MySql5.7InnoDB全文索引(针对中文搜索)
    spring cloud fegin传递request header
  • 原文地址:https://www.cnblogs.com/pdev/p/4069424.html
Copyright © 2011-2022 走看看