本题题意就是,给你一个数,这个数很大,要用高精度存,然后这个数由两个质数相乘得到,问你这两个质数中是否有一个小于L如果有,输出 BAD n,n为两个数中较小的那个,如果两个数都大于L,则输出 GOOD。
那么,我们来分析下题目。因为是由两个质数组成,我们可以先打个素数表。如果是sqrt(n)*n的枚举,依然太慢,所以这里要用筛选法。
void find()
{
int k=0;
prime[k++]=2;
for(int i=3;i<=1000100;i+=2)
{
bool bo=true;
for(int j=0;prime[j]*prime[j]<=i;j++)
if(!(i%prime[j]))
{
bo=false;
break;
}
if(bo)
prime[k++]=i;
}
return;
}
我们直接枚举每一位然后取模会很慢,所以我们可以3位一存,这样就提高了我们的运算效率。
下面是整道题的代码。#include<cstdlib>
#include<iostream>
#include<math.h>
#include<string>
#include<cstring>
using namespace std;
char a[200];
int l,len,lenjz,prime[100100],jz[200];
bool gjm(int x)//高精模
{
int ans=0;
for(int i=len-1;i>=0;i--)
{
ans=(ans*1000+jz[i])%x;
}
if(ans==0)return true;
return false;
}
void find()//求质数
{
int k=0;
prime[k++]=2;
for(int i=3;i<=1000100;i+=2)
{
bool bo=true;
for(int j=0;prime[j]*prime[j]<=i;j++)
if(!(i%prime[j]))
{
bo=false;
break;
}
if(bo)
prime[k++]=i;
}
return;
}
int main()
{
find();
while(1==1)
{
memset(jz,0,sizeof(jz));
scanf("%s%d",a,&l);
if(l==0&&a[0]=='0'&&strlen(a)==1)
break;
int lena=strlen(a);
len=(lena+2)/3;
for(int i=0;i<lena;i++)//转成3位一存,也就是10进制转1000进制
{
int lenjz=(lena+2-i)/3-1;
jz[lenjz]=jz[lenjz]*10+(a[i]-'0');
}
bool bo=true;
int i=0;
while(prime[i]<l)
{
if(gjm(prime[i]))
{
printf("BAD %d\n",prime[i]);
bo=false;
break;
}
i++;
}
if(bo)
printf("GOOD\n");
}
return 0;
}