思路
开始时,这个分数为 0 x \frac{0}{x} x0,每次分子 + 1 +1 +1,如果可以约分,就约分,问最大的操作次数。最多操作次数显然是不约分,每次分子 + 1 +1 +1。如何才能不约分,只要这个数是质数就可以。题目就简化成:给你一个数 n n n,请你求出离它最近且比他小的质数,这道题就好办了。
我用的是埃氏筛来求,具体代码:
void makeprime(ll n) {
for(long long i = 2; i <= n; i++) //从2开始往后筛.
{
if (!prime[i])
{
for(int j = i + i; j <= n; j += i)
{
prime[j] = 1;
}
}
}
}
有了这个质数表,每次我们就不用每到一个数就去检查,时间复杂度为 O ( n l o g l o g n ) O(n\,loglog\,n) O(nloglogn),普通筛为 O ( n l o g n ) O(n\,log\,n) O(nlogn)
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int prime[10000005];
void makeprime(ll n) {
for(long long i = 2; i <= n; i++) //从2开始往后筛.
{
if (!prime[i])
{
for(int j = i + i; j <= n; j += i)
{
prime[j] = 1;
}
}
}
}
int main(){
ios::sync_with_stdio(false);
makeprime(10000005);
ll t, n;
cin >> t;
while (t--) {
cin >> n;
for (int j = n; j >= n / 2; j--) {
if (prime[j] == 0) {
cout << j << endl;
break;
}
}
}
return 0;
}