• 扩展欧几里德算法 cogs.tk 2057. [ZLXOI2015]殉国


    2057. [ZLXOI2015]殉国

    ★☆   输入文件:BlackHawk.in   输出文件:BlackHawk.out   评测插件
    时间限制:0.05 s   内存限制:256 MB

    【题目描述】

    正义的萌军瞄准了位于南极洲的心灵控制器,为此我们打算用空袭摧毁心灵控制器,然而心灵控制器是如此强大,甚至能缓慢控制飞行员。一群勇敢的士(feng)兵(zi)决定投弹后自杀来避免心灵控制。然而自杀非常痛苦,所以萌军指挥官决定到达目的地后让飞机没油而坠落(也避免逃兵)。军官提供两种油:石油和中国输送来的地沟油,刚开始飞机没有油,飞机可以加几桶石油和几桶地沟油(假设石油和地沟油都有无限桶),飞机落地时必须把油耗尽,已知一桶石油和一桶地沟油所能支撑的飞行距离分别为a,b,驾驶员们必须飞往一个目的地,总距离为c.

    1.最少,最多需要加几桶油,若只有一种方案,最少和最多的是相同的.

    2.总共有多少种不同的加油配方(死法)能到达目的地。

    【输入格式】

    只有一行,三个正整数a,b,c

    【输出格式】

    两行,第一行为最少加几次油和最多加几次油,

    第二行为加油方法总数。

    若不存在任何方法,第一行输出-1 -1

    第二行输出0

    【样例输入】

    样例1:
    2 3 10
    样例2:
    6 8 10
    

    【样例输出】

    样例1:
    4 5
    2
    样例2:
    -1 -1
    0
    

    【提示】

    样例解释:

    样例一:飞机加两次石油,两次地沟油,总次数为4,2*2+3*3=10

    飞机加五次石油,不加地沟油,总次数为5,2*5+3*0=10

    总共两种

    样例二:飞机无法到达目的地

    数据范围:

    对于10%的数据,$a<=10^3,b<=10^3,c<=10^3$

    对于20%的数据,$a<=10^4,b<=10^4,c<=10^6$

    对于50%的数据,$a<=10^9,b<=10^9,c<=10^9$

    对于100%数据,$a<=3·10^{18},b<=3·10^{18},c<=3·10^{18}$

    三个答案分值权重分别为20%,30%,50% 

     1 /*
     2 65分代码:寻找方法数和最大值和最小值,都是用的暴力,实在没想出其他的方法。
     3 */
     4 #include<iostream>
     5 using namespace std;
     6 #include<cstdio>
     7 typedef long long ll;
     8 void exgcd(ll a,ll b,ll &x,ll &y,ll &gcd)
     9 {
    10     if(!b)
    11     {
    12         gcd=a;x=1;y=0;
    13         return ;
    14     }
    15     exgcd(b,a%b,x,y,gcd);
    16     ll t=x;
    17     x=y;
    18     y=t-(a/b)*y;
    19 }
    20 int main()
    21 {
    22     freopen("BlackHawk.in","r",stdin);
    23     freopen("BlackHawk.out","w",stdout);
    24     ll a,b,c,x,y,gcd,ans,minn,maxx;
    25     cin>>a>>b>>c;
    26     exgcd(a,b,x,y,gcd);
    27     if(c%gcd)
    28     {
    29         minn=maxx=-1;
    30         ans=0;
    31     }
    32     else
    33     {
    34         ll a0=a/gcd,b0=b/gcd;
    35         ll k=c/gcd;
    36         x*=k;y*=k;
    37         ans=0;
    38         if(x<0)
    39         {
    40             ll x1=-x;
    41             x1/=b0;
    42             x+=x1*b0;
    43             y-=x1*a0;
    44             if(x<0) x+=b0,y-=a0;
    45         }
    46         if(y<0)
    47         {
    48             ll y1=-y;
    49             y1/=a0;
    50             y+=y1*a0;
    51             x-=y1*b0;
    52             if(y<0) y+=a0,x-=b0;
    53         }
    54          minn=maxx=x+y;
    55         ll x2=x,y2=y;
    56         for(;y2>=0&&x2>=0&&x2<=c&&y2<=c;++ans)
    57         {
    58             minn=min(minn,x2+y2);
    59             maxx=max(maxx,x2+y2);
    60             x2+=b0;
    61             y2-=a0;
    62         }
    63         for(;y>=0&&x>=0&&x<=c&&y<=c;++ans)
    64         {
    65             minn=min(minn,x+y);
    66             maxx=max(maxx,x+y);
    67             x-=b0;y+=a0;
    68         }
    69         --ans;
    70     }
    71     if(ans==0) minn=maxx=-1;//
    72     cout<<minn<<" "<<maxx<<endl<<ans;
    73     fclose(stdin);
    74     fclose(stdout);
    75     return 0;
    76 }

    网上的AC代码:

    求exgcd,由xx=x*c/d+b/d*t0,yy=y*c/da/d*t0
    得到t的区间[l,r]
    方法数=r-l+1;
    因为方程线性,所以最值在l、r取到
    要写long double!!

     1 #include<cstdio>
     2 #include<cmath>
     3 #define min(x,y) x<y?x:y
     4 #define max(x,y) x>y?x:y
     5 using namespace std;
     6 long long a,b,c,d,x,y,xx,yy,ans1,ans2,ans;
     7 void exgcd(long long a,long long b,long long &d,long long &x,long long &y)
     8 {
     9     if(!b)  d=a,x=1,y=0;
    10     else exgcd(b,a%b,d,y,x),y-=x*(a/b);
    11 }
    12 int main()
    13 {
    14     freopen("BlackHawk.in","r",stdin);
    15     freopen("BlackHawk.out","w",stdout);
    16     scanf("%lld%lld%lld",&a,&b,&c);
    17     exgcd(a,b,d,x,y);
    18     if(!(c%d))
    19     {
    20         xx=ceil((long double)-x/b*c);
    21         yy=floor((long double)y/a*c);
    22         ans=yy-xx+1;
    23         ans1=x*c/d+y*c/d+(b-a)/d*yy;
    24         ans2=x*c/d+y*c/d+(b-a)/d*xx;
    25     }
    26     if(ans<=0) printf("-1 -1
    0");
    27     else printf("%lld %lld
    %lld",min(ans1,ans2),max(ans1,ans2),ans);
    28 }
  • 相关阅读:
    第 6 章 Android SDK 版本与兼容
    第 5 章 第二个 activity
    第 4 章 Android 应用的调试
    第 3 章 Activity 的生命周期
    第 2 章 Android 与 MVC 设计模式
    第 1 章 Android 应用初体验
    ACM基础之线性结构:一刷 参考答案
    小马慢慢跑
    Ubuntu 利用 xinetd 限制 SSH 连接数
    C# 定制 Attribute 简单使用
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5954578.html
Copyright © 2020-2023  润新知