【C语言】unsigned练习题帮助理解,数对(每日小细节003)

前言:

欢迎打开这篇博客,从今天开始,每天和大家分享一个C语言小细节,不久之后还会追加C++

一些常常被忽视的小细节和思想统一的编程题目是这个专栏的核心哦

虽然简单但千万别在细节处失分!!!!

每日花一两分钟浏览一下加深一个知识点不香吗

感兴趣的赶紧收藏关注起来吧,不要迷路~

目录

1.unsigned练习

2.数对


1.unsigned练习

快速回顾一下unsigned的常考细节

1.首先用unsigned视角看待数据没有符号位,所有都是数值位

2.unsigned char 的数据范围是0~2^8-1

  unsigned int 0~2^32-1

以此类推.....

详细讲解部在

https://blog.csdn.net/weixin_71138261/article/details/126253008?spm=1001.2014.3001.5501

现在可以轻松解决这个题 

循环次数是多少呢?

 

 有的小可爱就胡说了 每次-=3  当然从7——4——1就停止了

显然这是没学明白,首先数据的大小和变量是无关的,在

https://blog.csdn.net/weixin_71138261/article/details/126264107?spm=1001.2014.3001.5501

 这个部分 

 

 我们能知道,数据先变成计算机可以识别的补码,然后用前面的变量类型来决定怎么看待数据

比如数据-1

补码11111111 11111111 11111111 11111111

如果是 int a=-1;

那就默认存储的是-1

但如果是 char a=-1;

自然发生截断,因为char这个“容器”只能最多存储1字节——>11111111 还是-1

(小可爱就会说了,这不都是废话)

那是因为char 和int 都默认是signed

如果是unsigned int——>2^32

所以这个题远远没有这么简单

首先第一步是没错的7——>4——>1  循环次数是(7-1)/3+1=3

(为什么这么计算呢,挨个数就行了,循环比判断多一次,但是如果是i=1000000,你怎么数。。)

 所以1-3=-2(11111110)在unsigned看来就是255-1=254

从254再减到出现负号254%3=2 所以这次的循环次数是(254-2)/3+1=85次

此时变成-1(11111111)在unsigned看来就是255

此时正好再循环255/3=85次就变成0,循环结束

总次数3+85+85=173


 2.数对

 其实我们发现这个x%y>=k 就要求y要比k大,所以循环的时候从y=k+1开始即可

再看 x 的值必须小于n

因为y的值都是起点确定好

把n分成0~y    y~2y    ...

如果n%y<k,那么最后一个区间的长度中没有想要的x值

因为x只能在y的k邻域里

所以最后一个区间的x个数为0

反之n%y>=k   则最后一个区间的正确x值个数为(n%y)-(k-1)

除了最后一个区间,前面每一个区间的x个数都是y-k,这样的区间个数是n/y

最终实现

#include <stdio.h>
int main() {
    long n = 0;
    long k = 0;
   while( scanf("%ld%ld", &n, &k)!=EOF)
   { long count = 0;
   // long max = n > k ? n : k;
    //long min = n > k ? k : n;
    //for (  long a = 1; a <= max; a++) {
   //    for ( long b = 1; b <= max; b++) {
    //        if (a % b >= min) {
   //             count++;
   //         }
   //     }
   // }
   // printf("%ld", count);
    if(k==0)
    {printf("%ld\n",n*n);return 0;}
    for(long y=k+1;y<=n;y++)
    {
      long ans=n%y<k?0:(n%y)-k+1;
        count+=(n/y)*(y-k)+ans;
     }
    printf("%ld\n",count);
   }
}

有的小可爱就会问你注释的是什么,直接那样暴力解决不就得了还算来算去

那个暴力解法时间复杂度不符合要求。。


创作不易,感谢观看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值