列表

详情


NC201935. 单调栈

描述

对于一个 的排列 ,我们这样定义它的单调栈
对于 ,若 中比 小的数里最大的是 ,则 ,若不存在这样的数,则
现在你得到了 中某些位置的值,求一个字典序最小的 使得它满足这些值。
数据保证一定有解:数据的生成方式为先随机生成一个 ,然后求出它的 ,再随机去掉一些位置的值。
对于两个数组 ,前者的字典序比后者小,当且仅当存在某个 使得

输入描述

第一行一个正整数  表示数据组数
对于每组数据,第一行一个正整数 ,第二行 个整数表示 ,若 则表示这个 不知道是什么,你不需要去关心它。

输出描述

对于每组数据,输出一行  个整数,表示字典序最小的 ,注意不要有行末空格

示例1

输入:

3
4
-1 2 -1 2
6
1 -1 2 -1 3 -1
4
-1 -1 1 -1

输出:

1 3 4 2
1 3 2 5 4 6
2 3 1 4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 6ms, 内存消耗: 376K, 提交时间: 2020-02-01 17:13:08

#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int T,n,f[110],p[110],nowf,nowp;
int main(){
	scanf("%d",&T);
	while (T--){
		scanf("%d",&n);
		fo(i,1,n) scanf("%d",&f[i]);
		nowf=1;nowp=0;
		while (nowp<n){
			fd(i,n,1) if (f[i]==nowf) p[i]=++nowp;
			fo(i,1,n) if (f[i]==-1){
				f[i]=nowf;
				p[i]=++nowp;
				break;
			}else
				if (f[i]==nowf) break;
			nowf++;
		}
		fo(i,1,n-1) printf("%d ",p[i]);
		printf("%d\n",p[n]);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 10ms, 内存消耗: 608K, 提交时间: 2020-04-21 22:30:03

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t1,n,i,j,l,cnt,now,a[500010],b[500010];
int main(){
	scanf("%d",&t1);
	while(t1--){
		scanf("%d",&n);
		for(i=1;i<=n;i++)scanf("%d",&a[i]);
		for(i=1;i<=n;i++)b[i]=0;
		l=1;now=1;cnt=0;
		while(1){
			while(b[l]>0)l++;
			//printf("%d\n",l);
			if(l>n)break;
			if(a[l]==-1)a[l]=now;
			for(i=n;i>=l;i--)if(a[i]==now)b[i]=++cnt;
			now++;
		}
		for(i=1;i<=n;i++)printf("%d ",b[i]);puts("");
	}
}

上一题