// 1009. Mersenne Composite N
/* 梅森素数: 2^p -1 (p是素数,2^p -1也是素数)
题目大意:给出一个p<=63; 求出该范围内的梅森合数(2^k-1) k是素数
但 2^k-1 是合数的素数因子
如 23 * 89 = 2047 = ( 2 ^ 11 ) - 1
方法:先把0-2^p-1范围内的所有素数,放进一个数组prime内。方便之后的遍历
判断素数的方法是判断素数数组中是否有数可以整除该数,若有说明是合数
因为一个合数可以分解成若干个质数的乘积
然后从遍历2-p之间符合梅森合数的数merSennePrime,将它来对prime数组
的各个素数判断是否整除,若可,则更新该合数的值。即if(merSennePrime%prime[i]==0)
执行 merSennePrime /=prime[i],同时将因子存入fac数组中.直到遍历完整个prime或者
出现merSennePrime<= prime[i]。
最后判断merSennePrime是否前后发生变化,若变化了,说明是合数,遍历fac数组输出因子
*/
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_PRIME 200000
long long prime[MAX_PRIME];
long long fac[100];
long long countPrime;
long long countFac;
//此题先求出该范围内的所有素数,然后再遍历素数数组即可
bool createPrime(long long k)
{
countPrime = 0;
long long max = k > MAX_PRIME ? MAX_PRIME : k;
for(long long factor = 2; factor <= max; factor++)
{
long long maxDiv = (int)sqrtl(factor)+1;
bool isPrime = true;
for(int i=0; i<countPrime && prime[i] <=maxDiv; i++)
{
if(factor % prime[i] == 0)
{
isPrime = false;
break;
}
}
if(isPrime)
prime[countPrime++] = factor;
}
}
bool isPrime(int k)
{
if(k<2)
return false;
for(int i=2; i<=k/2; i++)
if(k % i == 0)
return false;
return true;
}
int main()
{
int k;
long long merSennePrime;
scanf("%d", &k);
merSennePrime = ((long long )1<<k) -1;
createPrime(merSennePrime);
for(int i=2; i<=k; i++)
{
countFac = 0;
if(isPrime(i)){
//printf(" ii %d ii", i);
merSennePrime = (long long )pow(2,(double)i)-1;
long long temp_prime = merSennePrime;
for(int j=0; j<countPrime && prime[j]< temp_prime; j++)
{
if(temp_prime % prime[j]==0)
{
temp_prime /= prime[j];
fac[countFac++] = prime[j];
}
}
if(temp_prime != merSennePrime )
{
fac[countFac++] = temp_prime;
printf("%lld", fac[0]);
for(int j=1; j<countFac; j++)
{
printf(" * %lld", fac[j]);
}
printf(" = %lld = ", merSennePrime);
printf("( 2 ^ %d ) - 1\n", i);
}
}
}
system("pause");
return 0;
}
Sicily.1009. Mersenne Composite N
最新推荐文章于 2014-10-05 19:07:00 发布