第十届蓝桥杯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次即可得出结果。结果同上,欢迎指正!