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

来源:互联网 发布:龙虎斗赌博押注软件 编辑:程序博客网 时间:2024/05/12 08:12

趣味数学题

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

212

Sample Output

15

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 longusing 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;}




0 0
原创粉丝点击