【入门】寻找雷劈数

题目描述

把整数3025从中剪开分为30和25两个数,此时再将这两数之和平方,计算结果又等于原数。
(30+25)*(30+25)=55*55=3025,这样的数叫“雷劈数”。
求所有符合这样条件的四位数。 (ab+cd)*(ab+cd)=abcd

输入

输出

若干行,每行一个雷劈数,从小到大输出。

代码如下:

#include<bits/stdc++.h>

bool isThunderboltNumber(int number) {

// 提取ab和cd
int ab = number / 100;
int cd = number % 100;

// 计算(ab + cd)的平方
int sum = ab + cd;
int square = sum * sum;

// 检查是否等于原数
return square == number;
}

int main() {
// 遍历所有四位数
for (int i = 1000; i <= 9999; ++i) {
if (isThunderboltNumber(i)) {
std::cout << i << " " ;
}
}

return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
雷劈是指一个如果是合,而且它的因子中含有“雷劈因子”(即7),则称这个为“雷劈”。根据定义,我们可以得到一个暴力的算法:枚举每个,然后判断它是否是合,再判断它的因子中是否包含7。但这个算法显然是不可取的,因为它的时间复杂度是 $O(n\sqrt{n})$,无法通过本题的大据测试。 实际上,我们可以根据“雷劈因子”的性质,设计一种更高效的算法。我们可以先枚举所有包含“雷劈因子”的字,然后对它们的倍进行标记,标记完成后,没有被标记的就是“雷劈”。 具体实现的过程是: 1.首先标记7的倍,即将它们的值全部置为1,表示它们不是“雷劈”。 2.然后标记其他包含“雷劈因子”的字的倍,比如 14、17、21、27、28、35 等等。这些字可以表示成 $7k+r$ 的形式,其中 $r$ 是 $1,2,4$ 中的一个。我们枚举 $r$,然后计算 $k$ 的取值范围,对于每个 $k$,将 $7k+r$ 倍的值置为1,表示它们不是“雷劈”。 3.最后,没有被标记的就是“雷劈”。 下面是一个实现: ```c #include <stdio.h> #include <string.h> #define MAX_N 1000000 char is_not_prime[MAX_N + 1]; int main() { memset(is_not_prime, 0, sizeof is_not_prime); is_not_prime[0] = is_not_prime[1] = 1; for (int i = 2; i <= MAX_N; i++) { if (!is_not_prime[i]) { if (i % 7 == 0) { // 7 的倍不是雷劈 is_not_prime[i] = 1; } else { for (int j = 1; j <= 3; j++) { // 遍历 r = 1, 2, 4 int x = i * 7 + j; if (x <= MAX_N) { // 防止越界 is_not_prime[x] = 1; } } } } } for (int i = 1; i <= MAX_N; i++) { if (!is_not_prime[i]) { printf("%d\n", i); } } return 0; } ``` 这里使用一个布尔组 `is_not_prime` 来标记每个是否是“雷劈”。组初始化为0,表示每个都不是“雷劈”。然后按照前面的算法,对于包含“雷劈因子”的字,将它们的倍标记为1,表示它们不是“雷劈”。最后,遍历组,输出没有被标记的,即为“雷劈”。 由于最大目可能达到1000000,我们需要使用一个布尔组来标记每个,以节省空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值