添加链接描述
H 题:
n 的范围是 1e6
大致的思路 就是 每一段 固定一个质数,然后这一段中的 数+下标 的和都是这个质数。
对于[1 n] 这些数 ,对于n 向前找到 一个比他大的最小的质数。假设这个质数=n+j 。那么也就是说 我n 这个数应该放在下标为j 的位置。那么我下标为j+1 的位置吗,应该放 n-1 ,这样递减的放下去。我下标为N 的位置 放的是 n - ( n- j ) 保证了他们和都是 n+j 这个质数 。我再[ j n] 之间存了 [n j ]
这样 对于我 [1 j-1] 的位置,是我这个问题的子问题。用相同的方法去做。
我寻找质数的大小范围是 (a ,2*a】.因为这里面 必定存在一个质数,所以我这个质数是一定能找到的。
代码可以递归去做,也可以递推去做。
时间复杂度是线性的
int n;cin>>n;
int i=n;
while(i>0)
{
int mnp=i+1;
while(!isprime(mnp))mnp++;
int mxi=mnp-i;
for (int j=i;j>=mxi;j--)
a[j]=mnp-j;
i=mxi-1;
}
添加链接描述
不能说 一模一样 只能说 完全不差一点
#include <bits/stdc++.h>
using namespace std;
int read()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
{
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
return x * f;
}
bool isprime(int x)
{
for (int i=2;i*i<=x;i++)
{
if (x%i==0)
{
return false;
}
}
return true;
}
void solve()
{
int n;cin>>n;
int i=2*n;
while(i>0)
{
int mnp=i+1;
while(!isprime(mnp))mnp++;
int mxi=mnp-i;
for (int j=i;j>=i-((i-mxi)/2);j--)
{
cout<<j<<" "<<mnp-j<<"\n";
}
i=mxi-1;
}
}
int main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int t=1;
cin>>t;
while (t--)
{
solve();
}
return 0;
}