极值问题(acms)

【问题描述】

已知m、n为整数,且满足下列两个条件:

① m、n∈{1,2,…,k},即1≤m,n≤k,(1≤k≤109)。

②(n2-m*n-m22=1

你的任务是:编程输入正整数k,求一组满足上述两个条件的m、n,并且使m2+n2的值最大。例如,从键盘输入k=1995,则输出:m=987   n=1597。

【输入样例】

1995

【输出样例】

m=987

n=1597

代码如下:

复制代码
 1     long m,n,k;
 2     double delt1,delt2,n1,n2;
 3     scanf("%d",&k);
 4     for(m=k;m>=1;m--)
 5     {
 6         delt1=sqrt(5*m*m+4);
 7         n1=(m+delt1)/2;
 8         n=n1;
 9         if(n==n1&&n<=k) break;
10 
11         delt2=sqrt(5*m*m-4);
12         n2=(m+delt2)/2;
13         n=n2;
14         if(n==n2&&n<=k) break;
15     }
16     printf("m=%d\nn=%d\n",m,n);
View Code
复制代码

批注:该算法确实挺好,简洁、高效率,但是有一个问题比较明显,那就是当k的值达到10^9时,for循环内,m从k开始向1遍历。当m的值取10^9时,计算delt的时候,m^2会溢出。而且并非只有当k达到10^9才会有这个问题,当k达到10^5时就会出现这个问题。想要自己写一个函数去实现高精度数的开平方根,似乎也不是这么容易。所以,可以看看下面的递推算法。

标准答案是:

代码如下:

复制代码
 1         int n=1,m=1,k,t;
 2     cin>>k;
 3     do
 4     {
 5         t=n+m;
 6         if(t<=k)
 7         {
 8             m=n;
 9                 n=t;
10         }
11     }
12     while(t<=k);
13     cout<<"m="<<m<<endl<<"n="<<n;
View Code
复制代码

批注:一开始阅读该算法,实在无法理解为何会是跟斐波那契数列一样的规律。后来查资料,阅读理解,终于看懂。下面做一个记录。

 

posted on   华山青竹  阅读(1666)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示