您的位置:首页 > 其它

2015 年 JXNU_ACS 算法组寒假第一次周赛 1008 趣味数学题

2015-01-25 15:39 316 查看

趣味数学题

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

2
1
2


Sample Output

1
5


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: