紫皮书--第二章(1)

第二章主要讲的是循环结构部分。学到的东西如下:

1、7744问题(输出形如aabb的完全平方数)

代码1:(sqrt取aabb平方根,将其转化为int型m,判断m*m是否和原数相等)

int main()
{
    for(int i=1;i<10;i++)
    {
        for(int j=0;j<10;j++)
        {
            int aabb=i*1000+i*100+j*10+j;
            int m = floor(sqrt(aabb) + 0.5);//为减小误差,采用四舍五入
            if(m*m==aabb)
                printf("%d\n",aabb);
        }

    }
    return 0;
}

floor()函数用于返回不大于x的最大整数。

int强制类型转换和floor()的区别:

int是向0取整,如1.8会变成1,-1.8会变成-1;

floor是向下取整,如1.8会变成1,-1.8会变成-2;区别就在于这里。还有一个区别是类型,int强制类型转换转换后是int型,而floor返回的是浮点型。

顺便扩展了一下,由于整数的表示范围远小于浮点数的表示范围,直接采用强制转换把浮点数转换成整数有可能出现数据错误,所以建议使用floor()函数实现”不大于X的最大整数“,完成对X的取整操作,如果想实现“向上取整”,则floor()之后再加1,表示方法为:floor(x)+1,输出方法为:%.0f不输出小数部分。

如果想实现“四舍五入”,则使用floor(x+0.5)。可以想象成在数轴上把一个单位区间往左移动0.5个单位的距离。floor(x)等于1的区间为[1,2),而floor(x+0.5)等于1的区间为[0.5,1.5)。

代码2:(我自己的做法,循环判断找出满足条件的)

int main()
{
    for(int i=1;i<10;i++)
    {
        for(int j=0;j<10;j++)
        {
            int aabb=i*1000+i*100+j*10+j;
            for(int m=0;m*m<9999;m++)
            {
                if(m*m==aabb)
                {
                    printf("%d\n",aabb);
                    break;
                }
            }
        }

    }
    return 0;
}

代码3:(枚举平方根,避免开平方的操作。书上的这个操作是x一直增大,寻找出x*x的值在1000到9999之间的数,再判断其前两位和后两位是否相等,也是个很清奇的思路啊)

int main()
{
    for(int x;;x++)
    {
        int n=x*x;
        if(n<1000)
            continue;
        if(n>9999)
            break;
        if((n/1000==n/100%10)&&(n%10==n%100/10))
            printf("%d\n",n);
    }
    return 0;
}

学到一点,continue是指跳回for循环的开始,执行调整语句并判断循环条件(即“直接进行下一次循环”),break是指直接跳出循环。以前一直以为continue即使继续,啥也不干,没有理解到这个层次。

2、3n+1问题

我的初始代码(看似没有问题,实际上是错误的没有考虑到n值太大,溢出问题)

int main()
{
    int n;
    scanf("%d",&n);
    int count=0;
    while(n!=1)
    {
        if(n%2==0)
            n=n/2;
        else
            n=n*3+1;
        count++;
    }
    printf("%d\n",count);
    return 0;
}

解决方案为改成long long类型(其范围是-2的64次方~2的64次方-1)

在当前流行的竞赛平台中,int都是32位整数,范围是-2147483648~2147483647,即-2的31次方~2的31次方-1。(以前以为int都是大于等于0的整数,把int和unsigned int搞混了,unsigned int是大于等于0的,范围是0~2的64次方-1)

本题中n的上限10的9次方只比int的上界稍微小一点,因此溢出了。哇,之前天真的以为只要比2的31次方-1小,哪怕一点点都是可以用int的,大错特错了,稍微小一点点溢出就变成了很正常的事情。

体会到了温故而知新,今晚就到这吧,over~

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值