趣味数学题
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 3 Accepted Submission(s) : 0
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
今有一道非常有趣的数学题:
已知x,y满足(x^2-x*y-y^2-1)*(x^2-x*y-y^2+1)=0
对于给定的正整数k,试求z=x^2+y^2的最大值,其中
x,y的取值范围都是[1,k],且都为整数。
Input
第一行有一个正整数t,代表有t组测试数据
每组测试数据包含一个正整数k。
Output
对于给定的k,输出z的最大值,每个数据占一行。
k的范围是[1,10^9]。
Sample Input
Sample Output
Author
JXNU_WY
由:
( n^2-mn-m^2 )^2=1
可得: n^2-mn-m^2=1或 n^2-mn-m^2=-1
最后求得n=(m+sqrt(5*m^2+4))/2或n=(m+sqrt(5*m^2-4))/2;
由于n,m都为整数 ,将m从1枚举到1000,如果n为整数则将它输出。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
for(int m=1;m<=1000;m++)
{
double x1=(m+sqrt(5.0*m*m+4))/2.0;
double x2=(m+sqrt(5.0*m*m-4))/2.0;
if(x2-(int)x2<1.0e-5) cout<<"m = "<<m<<" "<<"n = "<<(int)x2<<endl;
if(x1-(int)x1<1.0e-5) cout<<"m = "<<m<<" "<<"n = "<<(int)x1<<endl;
}
return 0;
}
求解的结果如下:
m = 1 n = 1
m = 1 n = 2
m = 2 n = 3
m = 3 n = 5
m = 5 n = 8
m = 8 n = 13
m = 13 n = 21
m = 21 n = 34
m = 34 n = 55
m = 55 n = 89
m = 89 n = 144
m = 144 n = 233
m = 233 n = 377
m = 377 n = 610
m = 610 n = 987
m = 987 n = 1597
相信你也看出来了,这尼玛满足条件的n,m是斐波那契数列相邻的项啊。
到了这里,这道题就非常简单了,给出一个k,要使得n^2+m^2最大,只要让n取所有小于等于k中最大斐波那契数,m取第二大的就可以了,例如当k=1995时,只需,让n=1597,m=987,就可以了。
C++参考代码如下:
#include<iostream>
#include<fstream>
#define LL long long
using namespace std;
LL f[100],k;
void init()
{
f[0]=1;f[1]=1;
for(int i=2;i<=90;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
cin.sync_with_stdio(false);
init();
int t;
cin>>t;
while(t--)
{
cin>>k;
int pos=0;
while(f[pos]<=k) pos++;
LL n=f[pos-1],m=f[pos-2];
cout<<(n*n+m*m)<<endl;
}
return 0;
}