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

先把素数打表,然后进行大数取模,要取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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值