第十屆藍橋杯C/C++組決賽A題題解
題目大意:
1、2019<X<Y
2、2019^2,X^2,Y^2構成等差數列,找出滿足條件的X,Y,並且X+Y最小。
分析1:暴力顯然。那麼如何確定循環變量的上界呢?對等差數列顯然有:2X^2>=22019Y,即
2019Y<=X^2。OK…暴力如下:
#include<iostream>
using namespace std;
int main()
{
int X=2020,Y=2021,flag=1;
for(;flag==1;X++){
for(Y=2021;2019*Y<=(X*X);Y++){
if((2*X*X-2019*2019)==Y*Y){
cout<<X<<" "<<Y<<endl;
flag=0;
break;
}
}
}
return 0;
}
輸出結果X=3111、Y=3909
分析2:雖然是填空題,暴力無傷大雅,且能很快跑出結果。那有沒有漂亮一點的暴力呢?
令a0=2019^2,公差爲d。
則數列:a0、a0+d、a0+2d要滿足題目要求,只需a0+d、a0+2d均爲平方數,那麼…
設a0+d=(2019+t)^2 ----> d=t(t+2*2019)。此時以t作爲循環變量搜索判斷,顯然會是一個更好的算法。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int d,a0=2019*2019,X,Y;
for(int t=1;;t++){
d=t*t+2*2019*t;
if(a0+d==sqrt(a0+d)*sqrt(a0+d)&&a0+2*d==sqrt(a0+2*d)*sqrt(a0+2*d)){
//cout<<x<<endl;
X=sqrt(a0+d);
Y=sqrt(a0+2*d);
cout<<"公差爲:"<<d<<endl;
cout<<"X="<<X<<endl;
cout<<"Y="<<Y<<endl;
break;
}
}
//驗證
cout<<X*X-a0<<endl;
cout<<Y*Y-X*X<<endl;
return 0;
}
事實上,這個算法只需循環t=1092次即可得出結果。結果同上,歡迎指正!