题目:
链接:https://ac.nowcoder.com/acm/contest/11253/K
来源:牛客网
示例1
输入
5 2
2 2
5 4
输出
1 2 5 3 4
示例2
输入
10 1
1 10
输出
-1
大致翻译:
给出数组b的大小和里面的一些数据,构造一个a数组使它满足以下伪代码:
且a中元素不能重复
我的思路:
先将b数组里的数据补充完整,b补充满足:
前一个给出b的数据在满足比后一个给出数据小的情况下往上递增,递增过程中不能比后一个给出的数据大;
再构造a数组,a满足:
从b数组中数据小的开始从右往左一次填入一个从1 递增的数据;
代码:
#include <bits/stdc++.h>
#define ll long long
typedef unsigned long long ull;
using namespace std;
const int N=1e6+10;
struct node{
int k;
int bb;
}c[N];
int b[N];
int a[N];
bool cmp(node x,node y){
return x.k <y.k ;
}
typedef struct {
int bl[N];
int size;
}nn;
int main()
{
int n,t,flag=0;int maxx=0;
cin>>n>>t;
c[0].bb=0,c[0].k =0;
for(int i=1;i<=t;i++){
cin>>c[i].k >>c[i].bb ;
b[c[i].k]=c[i].bb ;
maxx=max(maxx,c[i].bb);
if(c[i].k <c[i].bb )flag=1;
}
sort(c+1,c+t+1,cmp);
for(int i=1;i<t&&flag==0;i++){
if((c[i+1].k-c[i].k)<(c[i+1].bb-c[i].bb))flag=1;
}
if(flag)cout<<-1;
else{
for(int i=1,num=0;i<=t;i++){
for(int j=c[i-1].k+1;j<c[i].k ;j++){
if(num<c[i].bb )num++;
b[j]=num;
}
num=c[i].bb ;
}
for(int i=c[t].k;i+1<=n;i++){
b[i+1]=b[i];
}
nn d[maxx+10];
for(int i=n;i>0;i--){
int len=d[b[i]].size ;
d[b[i]].bl[len]=i;
d[b[i]].size++;
}
int shu=1;
for(int i=1;i<=maxx;i++){
for(int j=0;j<d[i].size;j++ ){
a[d[i].bl[j]]=shu++;
}
}
for(int i=1;i<=n;i++)cout<<a[i]<<' ';
}
return 0;
}
下面是大佬的代码:
(看代码就可以懂思路啦)
#include <bits/stdc++.h>
using namespace std;
map<int,int> mp;
#define ll long long
const int N =1e6+10;
int b[N],a[N];
int main()
{
int n,t,flag=0;
cin>>n>>t;
for(int i = 1;i <= t;i++)
{
int p,x;
cin>>p>>x;
if(p<x)flag=1;
b[p] = x;
}
if(flag)
{
cout<<'-1'<<endl;
return 0;
}
for(int i = 1; i <= n ;i++)
{
if(!b[i])
b[i] = b[i - 1] + 1;
}
for(int i = 2 ;i <= n;i++)
{
if((b[i] > b[i - 1] + 1) || (b[i] > i))
{
cout<<"-1"<<endl;
return 0;
}
}
stack<int> s;
int q = 1;
for(int i = n;i >= 1;i--)
{
while(s.size() < b[i])
s.push(q++);
a[i] = s.top();
s.pop();
}
for(int i = 1 ;i <= n;i++)
{
cout<<a[i]<<" ";
}
}