最近朋友问了我一道题,看了网上各种思路后,决定用栈来实现它
题目:
设计程序按从大到小的次序依次输出函数f(a,b)=2×a2+b2的最小的100个函数值及相应的两个参数的值,其中a和b均为自然数。
要求:
(1)作为函数值的存储结构应尽可能节省空间。
(2)所设计算法及整个程序的时间复杂度应尽可能小。
思路:
遍历每一个数result,找到符合2*a^2+b^2==result的a和b,下面代码中在0~50中找a和b,本题中可以缩小搜索范围,如果没找到,resul就加1,开始找下一轮。因为题目要求是从大到小的次序输出,而我们的result是从小到大开始遍历的,所以用到了栈,后进后出,这样就可以从大到小输出了。当然,你也可以定义数组来存储,倒序输出即可。
网上的另外一种方法是通过判断f(a+1,b)和f(a,b+1)谁更大来决定下一步是a++还是b++,但这样的方法会忽略一些值,与真实结果不符。
代码:
#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
typedef struct data
{
int a;
int b;
}data;
int f(int a, int b)
{
return 2*a*a+b*b;
}
int main()
{
data my; // 定义1个data空间,用于存储数据
stack<data> loc;
int a,b;
int count=0;//已得到的结果数`
int result=0;//目的结果
int flag=0;//判断a b是否可得出结果的标识
for (a=0; a<50;a++)//50控制循环数,可调,只要能得到100个结果,越小越好
{
for (b=0; b<50;b++)
{
int tmp=f(a,b);
if (tmp==result)//符合要求,输出,跳出,计算下一个
{
my.a = a;
my.b = b;
loc.push(my);
result++;//目的结果自增
flag=1;
count++;//计数器自增
break;
}
if (tmp>result)
break;
}
if (flag==1)
{
flag=0;
a=-1;
continue;
}
if (count==100)
break;
if (a==49)//a=49时还未得出结果,目的结果自增,从新计算下一个
{
result++;
a=-1;
continue;
}
}
while(!loc.empty())
{
cout<<loc.top().a<<" "<<loc.top().b<<" "<<f(loc.top().a,loc.top().b)<<endl;
loc.pop();
}
return 0;
}
结果