H - 素数表(POJ 2635)

题目链接
题解

题意:

  • 给两个正整数4 ⩽ \leqslant K ⩽ \leqslant 10100 和 2 ⩽ \leqslant L ⩽ \leqslant 106。要找两个素数因子,满足他们的乘积等于K,如果两个都不小于L,则输出GOOD,否输出BAD 和其中较小的那个。

思路:

  • 生成一个素数表。由于K很大,所以先将K当字符串处理存入数组,再化为千进制数,之后在L范围内遍历素数表,在循环到素数p时,将K从低位开始做模p加法,判断结果是否为0,若是则说明K能被一个小于L的素数整除,结束循环;若始终不为0,则两个素数因子都不小于L。
Code
#include <iostream>
#include <cstring>
#include <string>
#include <math.h>
#include <stdio.h>
#define N 1000001
using namespace std;//POJ 2635


string num;
int bignum[105];
int prime[N+5];
int size = 0;
bool isprime[N+5];

void getlist(int n)
{
    size=0;
    memset(isprime,0,sizeof(isprime));
    int d=sqrt((double)n)+1;
    for(int i=2;i<=n;i++)
    {
        if(isprime[i])continue;
        prime[++size]=i;
        if(i>d)continue;
        for(int j=2*i;j<=n;j+=i)
            isprime[j]=1;
    }
}



int main()
{
    int L, i, j, len, bit, tem, cnt, part_sum, flag, ans;
    getlist(N);
    while(cin>>num>>L)
    {
        if(num[0] == '0' && L == 0)
            break;

        len = num.size();
        bit = 0;
        cnt = 0;
        part_sum = 0;
        for(i =len-1; i >= 0; i--)
        {   
            tem = num[i]-'0';
            for(j = 0;j < bit; j++) tem *= 10;
            part_sum += tem;     
            if(bit == 2)
            {
                bignum[cnt] = part_sum;
                cnt++;
                bit = 0;
                part_sum = 0;
            }
            else    bit++;
        }
        if(part_sum != 0)
        {
            bignum[cnt] = part_sum;
            cnt++;
        }
        flag = 0;
        for(i = 1;prime[i] <= L  && i < size; i++)
        {        
            part_sum = 0;
            for(j = cnt - 1;j >= 0;j--)
                part_sum = (part_sum*1000 + bignum[j]) % prime[i];

            if(part_sum == 0)
            {
                flag = 1;
                ans = prime[i];
                break;
            }
        }
        if(!flag)
            cout<<"GOOD"<<endl;
        else
            cout<<"BAD"<<' '<<ans<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值