算法提高 Monday-Saturday质因子
时间限制:1.0s 内存限制:256.0MB
问题描述
这个问题是个简单的与数论有关的题目,看起来似乎是“求正整数的所有质因子”,但实际上并不完全是这样。
本题中需要定义以下几个概念:
1. Monday-Saturday数
对于一个正整数N,如果它除以7得到的余数是1或6,则可以写成N=7k+{1,6}的形式。更形象的,我们把这样的N称作“Monday-Saturday数”,简称“MS数”。
2. Monday-Saturday因子
如果对于两个MS数a,b,若存在一个MS数x,使得ax=b,那么就称a是b的一个“Monday-Saturday因子”,简称“MS因子”。
3. Monday-Saturday质数
如果对于MS数a,满足a>1且除了1和a之外a没有其他的MS因子,那么称a是一个“Monday-Saturday质数”,简称“MS质数”。
注:对于传统意义上的质数,若它是一个MS数,则它一定是一个MS质数。但反之不必成立,例如27,它是一个MS质数但不是传统意义上的质数。
4. Monday-Saturday质因子
如果对于两个MS数a,b,若满足a是b的MS因子且a是一个MS质数,那么称a是b的一个“Monday-Saturday质因子”。
例如:27是216的一个MS质因子(216=27*8)。
问题就是,给定一个MS数N,求其所有的Monday-Saturday质因子。
输入格式
每个输入数据包含多行,每行一个整数N(保证N一定是MS数,1<N<300000)。
输入的最后一行是一个整数1(对于这一行,你不必输出任何信息)。
每个输入数据不超过100行。
输出格式
对于每个N输出一行,表示N的所有Monday-Saturday质因子,按从小到大的顺序输出。格式形如“N: p1 p2 p3 …… pk”,注意行末无多余空格。
【样例输入】
205920
262144
262200
279936
299998
1
【样例输出】
205920: 6 8 13 15 20 22 55 99
262144: 8
262200: 6 8 15 20 50 57 69 76 92 190 230 475 575 874 2185
279936: 6 8 27
299998: 299998
数据规模和约定
1<N<300000,每个输入数据不超过100行。
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int main()
{
bool *is_not_MS_prime = new bool[300005];
vector<int> MS_primes;
memset(is_not_MS_prime, 0, 300005 * sizeof(bool));
for (int i = 6; i <= 300000; )
{
if (is_not_MS_prime[i] == 0)
{
MS_primes.push_back(i);
for (int k = 6; k * i <= 300000; )
{
is_not_MS_prime[k * i] = 1;
if (k % 7 == 6)
k += 2;
else
k += 5;
}
}
if (i % 7 == 6)
i += 2;
else
i += 5;
}
delete[] is_not_MS_prime;
int N;
cin >> N;
while (N > 1)
{
cout << N << ":";
for (int i = 0; i < MS_primes.size() && MS_primes[i] <= N; ++i)
{
if (N % MS_primes[i] == 0)
cout << " " << MS_primes[i];
}
cout << endl;
cin >> N;
}
return 0;
}