题意
传送门 HDU 2303
题解
若存在 K K K 的因数 a a a,那么 a a a 的最小质因数也是 K K K 的因数。埃氏筛法打表,从小到大枚举小于 L L L 的因数 p p p,判断 K K K 模 p p p 是否为 0 0 0 即可。
朴素的暴力
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 1000000
#define maxm 105
int L, prime[maxn + 1];
bool is_prime[maxn + 1];
char K[maxm];
int sieve(int n)
{
int p = 0, limit = sqrt(n);
fill(is_prime, is_prime + n, 1);
is_prime[0] = is_prime[1] = 0;
for (int i = 2; i <= n; i++)
{
if (is_prime[i])
{
prime[p++] = i;
if (i > limit)
{
continue;
}
for (int j = i * i; j <= n; j += i)
{
is_prime[j] = 0;
}
}
}
return p;
}
int _mod(char *s, int len, int m)
{
int res = 0;
for (int i = 0; i < len; i++)
{
res = (res << 3) + (res << 1) + s[i] - '0';
if (res >= m)
{
res %= m;
}
}
return res;
}
int main()
{
int p = sieve(maxn);
while (~scanf(" %s %d", K, &L) && !(K[0] == '0' && L == 0))
{
bool f = 1;
int rec = -1, len = strlen(K);
for (int i = 0; i < p; i++)
{
if (prime[i] >= L)
{
break;
}
if (_mod(K, len, prime[i]) == 0)
{
f = 0;
rec = prime[i];
break;
}
}
f ? puts("GOOD") : printf("BAD %d\n", rec);
}
return 0;
}
优化的暴力
封装一个基数较大的大数类,将 K K K 对每一个质数的求模所需要的模运算次数从 K K K 的位数减少为 K K K 的位数除以大数类的基数。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 1000000
#define maxm 105
typedef long long ll;
struct bigInt
{
#define base 100000000
int limit, a[15];
bigInt() {}
bigInt(char *s)
{
limit = -1;
int sum = 0, n = 1, len = strlen(s);
for (int i = len - 1; i >= 0; i--)
{
sum += n * (s[i] - '0');
n = (n << 3) + (n << 1);
if (n == base || i == 0)
{
a[++limit] = sum, sum = 0, n = 1;
}
}
}
int operator%(int m)
{
ll tmp = 0;
for (int i = limit; i >= 0; i--)
{
tmp = (tmp * base + a[i]) % m;
}
return tmp;
}
};
int L, prime[maxn + 1];
bool is_prime[maxn + 1];
char str[maxm];
int sieve(int n)
{
int p = 0, limit = sqrt(n);
fill(is_prime, is_prime + n, 1);
is_prime[0] = is_prime[1] = 0;
for (int i = 2; i <= n; i++)
{
if (is_prime[i])
{
prime[p++] = i;
if (i > limit)
{
continue;
}
for (int j = i * i; j <= n; j += i)
{
is_prime[j] = 0;
}
}
}
return p;
}
int main()
{
int p = sieve(maxn);
while (~scanf(" %s %d", str, &L) && !(str[0] == '0' && L == 0))
{
bool f = 1;
int rec = -1;
bigInt K(str);
for (int i = 0; i < p; i++)
{
if (prime[i] >= L)
{
break;
}
if (K % prime[i] == 0)
{
f = 0;
rec = prime[i];
break;
}
}
f ? puts("GOOD") : printf("BAD %d\n", rec);
}
return 0;
}