代码蠢事大合集

从今以后在这里记录自己查了半天才找出来的白痴BUG

核心主题:我是个傻福

C/C++相关

经典爆int不自知

  我确实没想到这么久过来我其实完全不会数字因子相关的内容
  这一次的最终代码是:

1
2
  int MaxNum = std::sqrt(n);
  for (int i = 2; i <= MaxNum; i++) {

  符合主题的,这是一个极度愚蠢的错误,我最初的代码写了:for(int i = 2;i * i <= n;i++)
  结合小标题,显而易见的是,我在运行过程中爆了int,但是其实这不是第一个爆了int的地方,但是这里是最致命的地方
  我们都知道,在C++中,爆了的数据要么占据符号位置变成了很小的负数,要么符号位没被占,但是超过的部分被忽略了导致数字变小了
  所以显而易见的,如果i*i爆了(毕竟临时容器当然也是int类型)就会导致死循环
  我说为啥单独一个点的时间会是其他点位的数百倍(或者说其实不止,但是测评不计录了)
  最后的解决方案目前想到两个:long long i = 2或者如现在的这个(其他的也不过是类似的而且效率其实不算高)
  但是毕竟每次循环都做一次乘法还是效率不够高,sqrt虽然涉及到类型转换以及精度丢失,但是在这里的算法影响不大可以忽略而速度可以提高两三倍
  还有就是:

1
2
3
4
5
6
      long long Product = i;
      int j = i;
      while (!(n % Product)) {
        j++;
        Product *= j;
      }

  按照我以前的思路,会习惯性地使用除法,但是在这里的精度丢失可能会有问题,所以还是经量用乘法代替除法
  不过我要说的不是这个,而是依然回归主题,这里其实也爆了,Product在累乗的过程中可能会爆,毕竟i可能会很接近sqrt(n),而n可能会很接近2^31,所以如果爆了还刚好可以整除就会出事
  **题外话:**这个方法长久不用了,我都忘了这个东西都开根了,到不了n本身,所以弄不到质数的因子,得特判一下

无价值的愚蠢

char数组初始化

  char M[] = {1, 2, 3, 'X', 9, 8.....},其实我想写的是'1'.'2'等等…

题目漏条件

  如题

写if把读入跳过了

  想写

1
2
3
4
5
6
    for (int j = 0; j < cnt; j++) {
      int idx;
      std::scanf("%5d", &idx);
      if (cnt > 1)
        flag[idx][0] = true;
    }

  把if写在了for的外围,导致条件不满足的时候读入错位了