NENU 密码破译III

Description

命案现场,死者用血写了Mersenne_prime(x),这样一个式子,可是x这个整数已经难以识别了,只能分辨出应该是2~64的一个整数。

为了协助破案,柯南需要求出3~64的梅森数,并且要确定它们是不是梅森素数。

如果不是梅森素数,柯南还需要对他们进行质因数分解,以探求他们之间的规律。

Input

输入有多组,每组输入数据占一行,包含一个整数x,2<=x<=64。

Output

如果 y = 2x - 1 是一个梅森素数,则输出一行:“y is Mersenne prime.”,

否则输出两行,第一行输出:“y is NOT Mersenne prime.”,第二行用空格分开,由小到大输出所有质因子。

Sample Input

2

3

4

Sample Output

3 is Mersenne prime.

7 is Mersenne prime.

15 is NOT Mersenne prime.

3 5

 

 

有关麦森素数与求质因子的结合。

可以使用unsigned long long 表示更大的数据。

麦森数是形如2^p-1的数,

如果一个麦森数是素数,我们称之为麦森素数

现在发现的麦森素数有以下:

P2,P3,P5,P7,P13,P19,P31,P61,P89,P107,P127等等。

 

分解一个数的质因子及其个数的模板如下:

ULL getPrimeFactor(ULL num,ULL* fc)
{
	ULL fcNum=0,j;
	for(ULL j=2;j*j<=num;j++)
	{
		if(num%j)
			continue;
		fc[fcNum++]=j;
		while(num%j==0)
			num/=j;
	}
	if(num!=1)
		fc[fcNum++]=num;
	return fcNum;
}

 

有了以上基础知识后,本题就好做了,但是对于P=64和P=62时要单独处理,通过打表发现。原因是:1.数据太大。2.质因子太大,算法运行时间过长,会超时。

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define ULL unsigned long long
using namespace std;

ULL MSS[]={2,3,5,7,13,17,19,31,61};
ULL x;
ULL ZPrim[1001];

ULL y(ULL x)
{
	return ((ULL)1<<x)-1;
}

ULL getPrimeFactor(ULL num,ULL* fc)
{
	ULL fcNum=0,j;
	for(ULL j=2;j*j<=num;j++)
	{
		if(num%j)
			continue;
		fc[fcNum++]=j;
		while(num%j==0)
			num/=j;
	}
	if(num!=1)
		fc[fcNum++]=num;
	return fcNum;
}

int main()
{
	while(scanf("%lld",&x)!=EOF)
	{
		memset(ZPrim,0,sizeof(ZPrim));
		bool flag=false;
		for(int i=0;i<9;i++)
			if(x==MSS[i])
				flag=true;
		if(flag)
			printf("%lld is Mersenne prime.\n",y(x));
		else
		{
			if(x==64)
            {
                printf("18446744073709551615 is NOT Mersenne prime.\n");
                printf("3 5 17 257 641 65537 6700417\n");
            }
            else if(x==62)
            {
                printf("%lld is NOT Mersenne prime.\n",y(x));
                printf("3 715827883 2147483647\n");
            }
            else
            {
                printf("%lld is NOT Mersenne prime.\n",y(x));
                ULL k=getPrimeFactor(y(x),ZPrim);
                printf("%lld",ZPrim[0]);
                for(ULL i=1;i<k;i++)
                    printf(" %lld",ZPrim[i]);
                printf("\n");
            }
		}
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值