从零学习算法竞赛3:aabb问题

       题目描述:

      输出所有形如aabb4位完全平方数(即前两位数字相等,后两位数字也相等)。

      分支和循环结合在一起时功能强大:下面列举所有可能的结果aabb,然后判断它们是否为完全平方数。注意a的范围是1~9,但b可以是0,主程序如下:

                                     for(int a=1;a<=9;a++)

                                          for(int b=0;b<=9;b++)

                                                   If(aabb是完全平方数)

                                                           printf“%d\n”,aabb);

        上面的程序并不完整——“aabb是完全平方数是中文描述,而不是合法的C语言表达式,而aabbC语言中也是另外一个变量,而不是把两个数字ab拼在一起。这个把这样不是真正程序代码成为伪代码(pseudocode)。虽然有一些正规的伪代码的定义,但在实际应用中,并不需要太拘泥于为代码的格式。主要的目标是描述算法梗概,避开细节,启发思路。

        不拘一格地使用伪代码来思考和描述算法是一种值得推荐的做法。

        写出伪代码之后,我们需要考虑如何把它变成真正的代码。上面的伪代码有两个非法的地方;完全平方数判定,以及aabb这个变量。后者相对比较容易;用另外一个变量n=a×1100+b×11存储即可。

        把伪代码写成代码时,一般先选择较为容易的任务来完成。

        接下来的问题就要困难一些了:如何判断n是否为完全平方数?

    方法一:

#include<stdio.h>
#include<math.h>
int main()
{
   for(int a=1;a<=9;a++)
      for(int b=0;b<=9;b++)
      {
	 int n=a*1100+b*11;//这里开始使用n,因此在这里定义n
	 i<span style="color:#FF0000;">nt <strong>m=floor(sqrt(n)+0.5);</strong></span>
   	 if(m*m==n)
	    printf("%d\n",n);
      }
   return 0;
}
 

         可不可以这样写?If(sqrt(n)==floor(sqrt(n))) printf(“%d\n”,n);即直接判断sqrt(n)是否为整数。理论上当然没问题,但这样写不保险,因为浮点数的运算(和函数)有可能存在误差。假设在经过大量计算后,由于误差的影响,整数1变成了0.99999999floor的结果会是0而不是1,。为了减少误差的影响,一般改成四舍五入,即floorx+0.5)。如果难以理解,可以想象在数轴上把一个单位区间左移0.5个单元的距离。Floorx)等于1的区间为【1,2】,而floorx+0.5)等于1的区间为【0.5,1.5.

         浮点运算可能存在误差。再进行浮点运算比较时,应考虑到浮点误差。

        总结:小数部分为0.5的数也会受到浮点误差的影响,因此任何一道严密的算法竞赛题目都需要想办法解决这个问题

         另一思路是枚举平方根x,从而避免开方操作。

      
<span style="font-size:18px;">#include<stdio.h>
int main()
{
   for(int x=33<span style="color:#FF0000;">;;</span>x++)     //for循环没有指定循环条件
   {
      int n=x*x;
      <strong>if(n>9999)
         break;
      int high=n/100;
      int low=n%100;
      if(high/10==high%10&&low/10==low%10)
	 printf("%d\n",n);
   }
   return 0;
}
答案为7744.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值