关于雷劈数的Java实现

[size=small]雷劈数:有位叫卡普利加的印度数学家。他在一次旅行中,遇到猛烈的暴风雨,电闪雷鸣过后,他看到路边一块牌子,被雷电劈成了两半,一半上写着30,另一半写着25。这时,卡普利加的脑中忽然发现了一个绝妙的数学关系:30+25=55 55^2=3025,把劈成两半的数加起来,再平方,正好是原来的数字。按照第一个发现者的名字,这种怪数被命名为“卡普利加数”或“雷劈数”。[/size]

package com.gzitc.plnum;

public class Demon {
/**
* isDemo(long num)判断参数num是否为雷劈数
* @param num
* @return
*/
public boolean isDemon(long num) {

//num1、num2是分出来的数
long num1,num2,t_num;

String ts = String.valueOf(num);
int length = ts.length();

//负数
if(ts.startsWith("-")) {
return false;
}

//位数小于两位
if(ts.length() < 2) {
return false;
}

//奇数位
if(length % 2 != 0) {
return false;
}

num1 = Long.parseLong(ts.substring(0,length/2));
num2 = Long.parseLong(ts.substring(length/2,length));

t_num = num1 + num2;

if(t_num * t_num == num) {
return true;
} else {
return false;
}

}

public static void main(String args[]) {
Demon d = new Demon();
for(long i = 10; i < 999999999; i++) {
if(d.isDemon(i)) {
System.out.print(i+" ");
}
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值