题解:P12051 [THUPC 2025 决赛] 排列与质数
我太菜了,一道绿题想不出来。还是 @zhikang 大神教我的。虽然他也看了官方题解。
首先锐评一下,这个构造题完全不同于正常的和出题人对脑电波的题,完全是个数学题,知道定理就一定会做,反之一定不会做。并且这个质数个数误导性也很强,差评。
思路
引理:伯特兰-切比雪夫定理:对于任意
那么先把
直到
因此此题结论可以加强成
代码
代码实现非常简单。AC 记录。
// NOTE: "[EDIT]" means you should edit this part by yourself
#include <bits/stdc++.h>
#define MULTITEST
using namespace std;
typedef long long ll;
#define rep1(i,x,y) for (int i = (x);i <= (y);i++)
#define rep2(i,x,y) for (int i = (x);i >= (y);i--)
#define rep3(i,x,y,z) for (int i = (x);i <= (y);i += (z))
#define rep4(i,x,y,z) for (int i = (x);i >= (y);i -= (z))
#define cl(a) memset(a,0,sizeof(a))
const int N = 1e5 + 10;
int n,cnt,k,pos;
bool visited[N];
int ans[N];
bool prime(int x)
{
for (int i = 2;i * i <= x;i++)
if (x % i == 0)
return false;
return true;
}
void solve()
{
cin >> n;
if (n <= 5)
{
rep1(i,1,n)
cout << i << ' ';
cout << '\n';
return;
}
k = n / 3;
cl(visited);
rep1(i,k,k * 2)
{
if (prime(i))
{
pos = i;
break;
}
}
cnt = 0;
ans[++cnt] = pos;
visited[pos] = true;
rep1(i,1,min(pos - 1,n - pos))
{
ans[++cnt] = pos - i;
ans[++cnt] = pos + i;
visited[pos - i] = true;
visited[pos + i] = true;
}
rep1(i,1,n)
if (!visited[i])
ans[++cnt] = i;
rep1(i,1,n)
cout << ans[i] << ' ';
cout << '\n';
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
#ifdef MULTITEST
cin >> t;
#else
t = 1;
#endif
while (t--)
solve();
}