题目
给你一个长度为 \(N\) 的整数序列 \(X\),请判断是否存在一个满足下列条件的整数序列 \(a\),如果存在,请构造一种方案
条件如下:
\(a\) 的长度为 \(N^2\),并且满足数字 \(1,2,3...N\) 都各出现恰好 \(N\) 次
对于 \(1\leq i\leq N\),数字 \(i\) 在 \(a\) 中第 \(i\) 次出现的位置是 \(X_i\)
分析
按照 \(X\) 从小到大排序,将 \(1\sim i-1\) 的数直接找空位填,倒过来再做一次就可以了
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=501; int ans[N*N],n;
struct rec{int x,rk;}a[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp(rec x,rec y){return x.x<y.x;}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i) a[i]=(rec){iut(),i};
sort(a+1,a+1+n,cmp);
for (rr int i=1;i<=n;++i){
ans[a[i].x]=a[i].rk;
rr int now=1;
for (rr int j=1;j<a[i].rk;++j){
for (;ans[now];++now);
if (now>a[i].x) return !printf("No");
ans[now]=a[i].rk;
}
}
for (rr int i=n;i;--i){
rr int now=n*n;
for (rr int j=1;j<=n-a[i].rk;++j){
for (;ans[now];--now);
if (now<a[i].x) return !printf("No");
ans[now]=a[i].rk;
}
}
printf("Yes\n");
for (rr int i=1;i<=n*n;++i) print(ans[i]),putchar(32);
return 0;
}