today,这道水题的大意为:输入三个整数数a,b(a≠b, a≤10000, b≤10000,c≤50000)(都可以无限取)和c,使a,b通过加或减得到c,输出最少要几个a,b,用n,m表示,且n+m要最小(这题每次有k组数据,以输入0 0 0为结束);
当我看到这道题时,第一个思路是模拟,就是n,m初值附0,然后枚举,这是个思路,代码如下:
#include<bits/stdc++.h>
using namespace std;
int a,b,c,d,minn=100000,minnn=1000000,x,y;
int main()
{
while(1)
{
cin>>a>>b>>c;
if(a==0||b==0||c==0) break;
for(int i=0;i<=10000;i++)//枚举暴力
for(int j=0;j<=10000;j++)//暴力枚举
if(a*i+b*j==c||a*i-b*j==c||b*j-a*i==c)//判断,若满足,记录状态
{
if(i+j<minn)
{
minn=i+j;
if(a*i+b*j<minnn)//判断是否最优
x=i;y=j;break;
}
x=i;
y=j;
d=0;
}
}
cout<<x<<' '<<y;
}
显然,从0枚举到10000已经是10^8还要计算,肯定会爆的。
然后,发现枚举n,m不行,那就可以反过来,让a,b翻倍,在相减得到c,这个方法应该是可行的,但我还是优化了一下,可以让a或b不变,另一个数翻倍,再减去c,看看是否满足条件,不过这样有两种情况,会有点累。但一时疏懒的我还是这样敲了:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,c;
while(1)
{
cin>>a>>b>>c;
int aa=0,bb=b,ana=0,anb=0,aaa,bbb,aa1,bb1;
if(a==0&&b==0&&c==0) return 0;
while(1)//这里让aa即a翻倍
{
if((aa-c)%bb==0)//判断是否满足条件
{aaa=ana,bbb=max((aa-c)/bb,-(aa-c)/bb)/*记录状态并更新*/;break;}
aa+=a,ana++;//翻倍
}
/*下同*/
aa=a,bb=0;
while(1)
{
if((bb-c)%aa==0)
{aa1=max((bb-c)/aa,-(bb-c)/aa),bb1=anb;break;}
bb+=b;anb++;
}
if(aaa+bbb>aa1+bb1)/*找最优*/ cout<<aa1<<' '<<bb1<<endl;
else cout<<aaa<<' '<<bbb<<endl;
}
}
这代码看起来很low,确实有很多可以改进的地方,比如变量名就很low,还有附初值时可以简单判断,然后附适当的值,相当于减少计算量,如果您是大佬,也可以帮在下把两种情况压成一种情况。不过,我还是0ms的时间A的,so就不想优化了。