最近朋友问了我一道题,看了网上各种思路后,决定用栈来实现它
题目:
设计程序按从大到小的次序依次输出函数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++,但这样的方法会忽略一些值,与真实结果不符。
代码:
1. #include<iostream> 2. #include<stdio.h> 3. #include<stack> 4. using namespace std; 5. 6. typedef struct data 7. { 8. int a; 9. int b; 10. }data; 11. 12. int f(int a, int b) 13. { 14. return 2*a*a+b*b; 15. 16. } 17. 18. int main() 19. { 20. data my; // 定义1个data空间,用于存储数据 21. stack<data> loc; 22. int a,b; 23. int count=0;//已得到的结果数` 24. int result=0;//目的结果 25. int flag=0;//判断a b是否可得出结果的标识 26. for (a=0; a<50;a++)//50控制循环数,可调,只要能得到100个结果,越小越好 27. { 28. for (b=0; b<50;b++) 29. { 30. int tmp=f(a,b); 31. if (tmp==result)//符合要求,输出,跳出,计算下一个 32. { 33. my.a = a; 34. my.b = b; 35. loc.push(my); 36. result++;//目的结果自增 37. flag=1; 38. count++;//计数器自增 39. break; 40. } 41. if (tmp>result) 42. break; 43. } 44. 45. if (flag==1) 46. { 47. flag=0; 48. a=-1; 49. continue; 50. } 51. 52. if (count==100) 53. break; 54. 55. if (a==49)//a=49时还未得出结果,目的结果自增,从新计算下一个 56. { 57. 58. result++; 59. a=-1; 60. continue; 61. } 62. } 63. 64. while(!loc.empty()) 65. { 66. cout<<loc.top().a<<" "<<loc.top().b<<" "<<f(loc.top().a,loc.top().b)<<endl; 67. loc.pop(); 68. } 69. 70. 71. return 0; 72. 73. }
结果