题目描述
You are given an integer sequence x of length N. Determine if there exists an integer sequence a that satisfies all of the following conditions, and if it exists, construct an instance of a.
a is N2 in length, containing N copies of each of the integers 1, 2, …, N.
For each 1≤i≤N, the i-th occurrence of the integer i from the left in a is the xi-th element of a from the left.
Constraints
1≤N≤500
1≤xi≤N2
All xi are distinct.
输入
The input is given from Standard Input in the following format:
N
x1 x2 … xN
输出
If there does not exist an integer sequence a that satisfies all the conditions, print ‘No’. If there does exist such an sequence a, print ‘Yes’.
样例输入
3
1 5 9
样例输出
Yes
题意:原题位于AtCoder,给出一个长度为n的序列a,要我们构造长度为n^2的序列b,在这个构造序列中要求满足,对于序列a中的元素,我们将在序列b中的第a【i】个位置恰好第i次出现数字i,即,a【i】表示了下标i在a【i】的第i次出现位置,所有1~n个数字都必须出现n次。在满足了第a【i】位出现第i次后,后续数位上的出现不做要求。 若能构造出这样的序列b输出Yes,否则输出No.
根据题意模拟构造即可,首先根据每个下标I的第i次出现位置从小到大排序,我们将优先排列出现在较前位置的数字。使得位置靠前的数字能在前a【i】个位置中有足够的空间放置i-1个数量。
对于某一个数,当我们发现排列的指针在构造i-1个数量的i时,位置超过了a【i】,说明构造失败,直接输出No
在正向构造完之后,我们满足了每个数字应该在第a【i】位前放置i个i的条件,接下来就要满足整个序列中所有数的出现次数都是n的条件,接着刚才的指针向后填数,此时我们需要填的i的个数是n-pos个,此时注意,如果之前的val太大,那么序列的后半部分可能不够填n-pos个i,那么就要填在val之前,这样就会影响val的出现次数不是i,所以也是无解的情况,因此如果填数的指针小于val那么说明一定会影响到val的排位。
代码如下
#include<bits/stdc++.h>
using namespace std;
struct num
{
int val,pos;
} a[508],b[508];
bool cmp(num a,num b)
{
return a.val<b.val;
}
int ans[508*508];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
bool flag=true;
memset(ans,0,sizeof(ans));
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i].val);
b[i].val=a[i].val;
b[i].pos=a[i].pos=i;
}
sort(b+1,b+n+1,cmp);
int it=1;
for(int i=1; i<=n; i++)
{
ans[a[b[i].pos].val]=b[i].pos;
for(int j=1; j<b[i].pos; j++) ///在第val为之前要填充pos个pos
{
while(ans[it])it++;///只能在没有被填数的位置填
ans[it]=b[i].pos;
}
if(it>a[b[i].pos].val)///若填充超量说明根本不够构造
{
printf("No
");
flag=false;
break;
}
}
if(!flag) continue;
for(int i=1; i<=n; i++) ///对于所有数,先正向填充,保证在val前能填充够pos个
{
for(int j=1; j<=n-b[i].pos; j++) ///再继续填充,前pos个能保证的情况下,在剩余空位能填充够n个
{
while(ans[it])it++;
if(it<a[b[i].pos].val)
{
printf("No
");
flag=false;
break;
}
ans[it]=b[i].pos;
}
if(!flag) break;
}
if(flag)printf("Yes
");
// for(int i=1; i<=n*n; i++)printf("%d ",ans[i]);
}
}