您的位置:首页 > 其它

poj 2635

2013-03-06 11:16 148 查看
题目大意:给你一个数,已经确定是两个素数的乘积.问你,两个素数中有没有一个数小于给定的L,如果有,就输出"BAD "+这个数.没有则输出"GOOD".

思路:1.首先由于给的数据很大.所以在判断上要用大数模的运算.将这个数以字符的形式存储.并将它转化成10w进制从个位开始.列如:123456789=[1234][56789]设选定的prime为e,将[1234]%e=r;判断([56789]+r*100000)%e是否等于0.

2.素数筛选:

int prime[SIZE];//若设成全局变量,则默认为0;

prime[0]=2;
int top=1;
for(int i=3;i<L;i+=2)

{
int flag=0;
for(int j=0;prime[j]*[j]<=L;j++)

{
if(i%prime[j]==0){flag=1;break;}
}
if(!flag)prime[top++]=i;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000101
using namespace std;
char s[110];
__int64 w[50];
__int64 pri[1000000];
int b;
void primemake()
{
int ii,jj;
int num=0;
pri[0]=2;
for(ii=3;ii<N;ii+=2)//这里其实可以优化成ii+=2
{
int flag=0;
for(jj=0;pri[jj]*pri[jj]<=ii;jj++)//开方
{
if(ii%pri[jj]==0){flag=1;break;}
}
if(flag==0){pri[++num]=ii;}
}
return ;
}
int ppow(int tt)
{
int l;
int mm=1;
for(l=1;l<tt;l++)
{
mm*=10;
}
return mm;
}//求10^tt
void change(int len)
{
int k;
k=len%5;
int nu=0;
b=0;
for(int l=0;l<k;l++)
{
nu+=(s[l]-'0')*ppow(k-l);
}
w[b++]=nu;
for(int l=k;l<len;l+=5)
{
nu=0;
for(int h=l;h<l+5;h++)
{
nu+=(s[h]-'0')*ppow(5-(h-l));
}
w[b++]=nu;
}
return ;
}//将数组s[]转化成10w进制,如123456789转化成[1234][56789],并存于w[]数组中
int judge(int p)
{
__int64 r=0;
for(int l=0;l<b;l++)
r=(w[l]+r*100000)%p;
if(r==0)return 1;
else return 0;
}
int main()
{
primemake();
int i,j,m,n;
while(scanf("%s %d",s,&n),(s[0]!='0')||n)
{
int t=strlen(s);
int mark=0,pp;
change(t);
for(i=0;pri[i]<n;i++)//直接在这个范围里面寻找是否存在这样的数
{
if(pri[i]==0)break;//由于可能存在的最小的素数不小于n,则会进入死循环
if(judge(pri[i])){mark=1;pp=pri[i];break;}
}
if(mark==1)printf("BAD %d\n",pp);
else printf("GOOD\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: