codeup25955 极值问题(NOI1995)

3 篇文章 0 订阅

codeup25955  极值问题(NOI1995)

时空限制    1000ms/128MB

题目描述

已知m、n为整数,且满足下列两个条件:
    ① m、n∈1,2,…,K,(1≤K≤10^9)
    ② (n^ 2-mn-m^2)^2=1
编一程序,对给定K,求一组满足上述两个条件的m、n,并且使m^2+n^2的值最大。例如,若K=1995,则m=987,n=1597,则m、n满足条件,且可使m^2+n^2的值最大。

输入

输入仅一行, K 的值。

输出

输出仅一行, m^2 n^2 的值

样例输入

1995

样例输出

3524578


分析

m^2n^2最大,那么m,n最大。如何保证?

看第2个条件

(n^ 2-mn-m^2)^2=1

(m^2+mn-n^2)^2=1

提取公约数:

((m+n)^2-mn-n^2-n^2)^2=1

((m+n)^2 - (m+n)n - n^2)^2=1     ........条件3

观察条件3和条件2的区别

条件2:(n^ 2-mn-m^2)^2=1

统计3:((m+n)^2 - (m+n)n - n^2)^2=1

n->m+n(第1个平方)

n->m+n,m->n(第2个式子)

m->n(第2个平方)

这个就是斐波那契数列。m、n都是在<=K之内的最大的两个满足斐波那契数列的数
另外由于1≤K≤10^9可能m、n数字较大,要用long long 类型

斐波那契数列:0 1 1 2 3 5 ....  (结合条件1)带入其中两项1,1,就可以了。


代码

法一:迭代法
#include<iostream>
using namespace std;

int main(){
	long long n,m,k,t;
	cin>>k;
	n=m=1LL;
	while (n<=k){
		t=n+m;
		m=n;
		n=t;
	}
	t=(n-m)*(n-m)+m*m;
	cout<<t<<endl;
	return 0;
}

法二:数组

#include<iostream>
using namespace std;
long long a[100];
 
int main(){
    long long m,n,k;
    cin>>k;
    a[1]=a[2]=1LL;
    int i=3;
    while (1){
        a[i]=a[i-2]+a[i-1];
        if (a[i]>k) break;
        i++;
    }
    cout<<a[i-2]*a[i-2]+a[i-1]*a[i-1]<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值