添加链接描述
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;
}