您的位置:首页 > 其它

POJ 2635 N进制大数与小数取模

2011-12-24 18:25 344 查看
先把素数打表,然后进行大数取模,要取N进制(最好5<=N<=10)进行大数取模运算,否则超时(1000000内的素数个数达78498个)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define MLEN 10//每位存pow(10,MELN)进制(即每个位存放MLEN位数)
#define MAXN 1000000
bool prime[MAXN + 10] = {1,1,0};
int mymap[MAXN + 10];
int NumPrime[MAXN + 10];
void ComputePrime()
{
int i,j,sub;
sub =  -1;
for(i = 2;i<=MAXN;i++)
{
mymap[i] = sub;
if(prime[i] == 0)
{
sub++;
NumPrime[sub] = i;
mymap[i] = sub;

for(j = i + i;j <= MAXN;j += i)
{
prime[j] = 1;
}

}
}
sub++;
}//打素数表
bool  divide(long long   numd[],int n,long long  numb,int len)//numd是一个pow(10,10)进制的数。并且由高位到低位排,即与输入相反
{
int i;
long long  carry;
long long  num = pow(10,MLEN);
for(i = n-1;i >= 0;i--)
{

carry = numd[i] % numb;

if(i == 1&&len % MLEN !=0)
{
num = len % MLEN;
num = pow(10,num);
}
numd[i - 1] = carry * num + numd[i -1];

}
if(carry == 0)
{
return true;
}
return false;
}//大数与小数取模
int main()
{
char numa[110];
long long  numc[110];
long long  numd[110];
long long  nume[110];
int numb;
int len;
int i;
int t;
int temp;
int sub;
int j;
ComputePrime();
while(scanf("%s %d",numa,&numb) != EOF)
{
if(strcmp(numa,"0")==0 && numb == 0)
{
break;
}
memset(numc,0,sizeof(numc));
len = strlen(numa);
sub = 0;
for(i = 0;i < len;i++)
{
t = MLEN;
temp = MLEN;
if(len - i < temp)
{
temp = len - i;
}
temp--;
while(t--&&i<len)
{

numc[sub] += pow(10,temp) * (numa[i] - '0');
temp--;
i++;
}
i--;
sub++;
}
temp = sub - 1;
for(i = 0;i < sub;i++)
{
numd[i] = numc[temp--];
}//倒序过来,由大到小排
int i = -1;
i = mymap[numb];
if(NumPrime[i] == numb)
{
i--;
}
int ans = -1;
j = i;
i = 0;

while(i<=j)
{
memcpy(nume,numd,sizeof(numd));
if(divide(numd,sub,NumPrime[i],len))
{
ans= NumPrime[i];
break;
}
memcpy(numd,nume,sizeof(numd));
i++;

}
if(ans == -1 )
{
printf("GOOD\n");
}
else
{
printf("BAD %d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: