洛谷题目链接:CF911E Stack Sorting

Codeforces题目链接:Stack Sorting

题意翻译

给你一排列的一部分,让你补全整个排列使其字典序最大并且经过一个栈调整顺序之后能够顺序输出

题目描述

Let's suppose you have an array aa , a stack ss (initially empty) and an array bb (also initially empty).

You may perform the following operations until both aa and ss are empty:

  • Take the first element of aa , push it into ss and remove it from aa (if aa is not empty);
  • Take the top element from ss , append it to the end of array bb and remove it from ss (if ss is not empty).

You can perform these operations in arbitrary order.

If there exists a way to perform the operations such that array bb is sorted in non-descending order in the end, then array aa is called stack-sortable.

For example, [3,1,2][3,1,2] is stack-sortable, because bb will be sorted if we perform the following operations:

  1. Remove 33 from aa and push it into ss ;
  2. Remove 11 from aa and push it into ss ;
  3. Remove 11 from ss and append it to the end of bb ;
  4. Remove 22 from aa and push it into ss ;
  5. Remove 22 from ss and append it to the end of bb ;
  6. Remove 33 from ss and append it to the end of bb .

After all these operations b=[1,2,3]b=[1,2,3] , so [3,1,2][3,1,2] is stack-sortable. [2,3,1][2,3,1] is not stack-sortable.

You are given kk first elements of some permutation pp of size nn (recall that a permutation of size nn is an array of size nn where each integer from 11 to nn occurs exactly once). You have to restore the remaining n-kn−k elements of this permutation so it is stack-sortable. If there are multiple answers, choose the answer such that pp is lexicographically maximal (an array qq is lexicographically greater than an array pp iff there exists some integer kksuch that for every i<ki<k q_{i}=p_{i}qi​=pi​ , and q_{k}>p_{k}qk​>pk​ ). You may not swap or change any of first kk elements of the permutation.

Print the lexicographically maximal permutation pp you can obtain.

If there exists no answer then output -1.

输入输出格式

输入格式:

The first line contains two integers nn and kk ( 2<=n<=2000002<=n<=200000 , 1<=k<n1<=k<n ) — the size of a desired permutation, and the number of elements you are given, respectively.

The second line contains kk integers p_{1}p1​ , p_{2}p2​ , ..., p_{k}pk​ ( 1<=p_{i}<=n1<=pi​<=n ) — the first kk elements of pp . These integers are pairwise distinct.

输出格式:

If it is possible to restore a stack-sortable permutation pp of size nn such that the first kk elements of pp are equal to elements given in the input, print lexicographically maximal such permutation.

Otherwise print -1.

输入输出样例

输入样例#1:

5 3

3 2 1

输出样例#1:

3 2 1 5 4

输入样例#2:

5 3

2 3 1

输出样例#2:

-1

输入样例#3:

5 1

3

输出样例#3:

3 2 1 5 4

输入样例#4:

5 2

3 4

输出样例#4:

-1


一句话题意: 给出一个长度为\(n\)的排列的前\(k\)个,你需要构造第\(k+1\)到第\(n\)个使得这些数字按顺序入栈并在入栈后任意时候出栈可以使出栈顺序为\(1\)~\(n\).如果无法构造出这样的排列则输出\(-1\).如果存在多组解则输出字典序最大的那一个.


话说这道题是我在CF上第一道非比赛时A掉的题目,也是第一个超过C题的题目...

题解: 首先考虑判断\(-1\)的情况.其实前\(k\)个已经确定了,那么我们就可以直接从小到大的插入数字并判断.因为我们要求出栈的顺序是从小到大的,所以如果我们从小的开始插入,那么插入这个小数字之后马上就可以弹出栈,这样模拟过一遍之后就可以判断前\(k\)个是否能组成一组合法解.

然后再来考虑这个字典序的问题.既然要求字典序最大,那么显然能放一个大的数字就不能放比它小的.然后我们会发现,如果\(k==0\),那么后面的\(n\)个就可以直接从\(n\)到\(1\)构造. 也就是说,只要我们把前\(k\)个已经固定了的数字全部都能弹出栈之后,那么后面直接降序输出就可以了.

这里我们记录前\(k\)个元素中未被弹出栈的元素的最小值,然后将后来从小到大枚举变成从最小值-1开始枚举直到出现被选用的数字停下就可以了.

如果不懂看一下代码理解一下吧.

#include<bits/stdc++.h>
using namespace std;
const int N=200000+5;
const int inf=2147483647; int n, k, a[N], vis[N], stk[N], ins[N], top = 0, cnt = 0, mn[N], topmn = 0, len = 0;
//vis记录一个数字是否已经被选用
//mn记录未被选用的数字的最小值(每一个可能成为最小值的数字都要记录进来)
//topmn为mn栈的栈顶指针
//ins记录前k个数字是否已经被弹出栈
//stk模拟放入数字的栈,top是它的栈顶 bool check(){
int i = 1, pos = 1;
while(i <= k){
stk[++top] = a[i], vis[a[i]] = ins[a[i]] = 1, i++;
while(top && stk[top] == pos) pos++, ins[stk[top--]] = 0;
}
for(int j=1;j<=n;j++){//直接从小到大放入数字,能取出就把数字都取出
if(!vis[j]) stk[++top] = j;
while(top && stk[top] == pos) ins[stk[top--]] = 0, pos++;
}
for(int i=1;i<=n;i++)
if(ins[i]) return false;//如果仍有数字未被取出,则无法构成合法排列
return true;
} void work(){
int i = 1, pos = 1, st = 0; top = 0, topmn = 0, mn[0] = inf, len = k;
//cnt记录第1~k个数字中有几个没被弹出栈
memset(vis, 0, sizeof(vis)); memset(ins, 0, sizeof(ins));
vis[0] = 1;//重复使用数组需要清空
//vis[0]=1是为了防止数组判断越界
for(int j=1;j<=k;j++) st = max(st, a[j]);//st记录最后一个数字被弹出栈的位置,之后的就直接倒序输出就可以了
while(i <= k){//模拟
stk[++top] = a[i], vis[a[i]] = ins[a[i]] = 1, cnt++;
if(mn[topmn] > a[i]) mn[++topmn] = a[i];
while(top && stk[top] == pos){
if(mn[topmn] == stk[top]) topmn--;
pos++, ins[stk[top--]] = 0, cnt--;
}
i++;
}
while(cnt){
for(int j=mn[topmn]-1;vis[j] == 0;j--){//注意这里的枚举顺序
stk[++top] = j, a[++len] = j, vis[j] = 1;
while(top && stk[top] == pos){
if(mn[topmn] == stk[top]) topmn--;
if(ins[stk[top]]) ins[stk[top--]] = 0, pos++, cnt--;
else top--, pos++;
}
}
}
for(int i=st+1;i<=n;i++) a[i] = n-i+1+st;
for(int i=1;i<=n;i++) cout << a[i] << ' '; cout << endl;
} int main(){
// freopen("data.in", "r", stdin);
ios::sync_with_stdio(false);
cin >> n >> k;
for(int i=1;i<=k;i++) cin >> a[i];
if(check()) work();
else cout << -1 << endl;
return 0;
}

CF911E Stack Sorting的更多相关文章

  1. Codeforces 911E - Stack Sorting

    911E - Stack Sorting 思路: 用栈来模拟,能pop就pop,记下一个需要pop的数为temp,那么如果栈非空,栈顶肯定大于temp,那么加入栈 栈顶值-1 到 temp 的值,否则 ...

  2. Stack Sorting CodeForces - 911E (思维+单调栈思想)

    Let's suppose you have an array a, a stack s (initially empty) and an array b (also initially empty) ...

  3. 数据结构设计 Stack Queue

    之前在简书上初步总结过几个有关栈和队列的数据结构设计的题目.http://www.jianshu.com/p/d43f93661631 1.线性数据结构 Array Stack Queue Hash ...

  4. Educational Codeforces Round 35

    Nearest Minimums 相同的数里最小的数里的最小距离 Solution Two Cakes Solution Three Garlands 瞎比试 Solution Inversion C ...

  5. C# 集合类 :(Array、 Arraylist、List、Hashtable、Dictionary、Stack、Queue)

    我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashTable类.我们经常用HashTable 来存储将要写入到数据库或者返回的信息,在这之间要不断的进行类型的转化,增加了系统装箱和 ...

  6. [POJ1007]DNA Sorting

    [POJ1007]DNA Sorting 试题描述 One measure of ``unsortedness'' in a sequence is the number of pairs of en ...

  7. URAL(timus) 1280 Topological Sorting(模拟)

    Topological Sorting Time limit: 1.0 secondMemory limit: 64 MB Michael wants to win the world champio ...

  8. Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 连续LIS

    C. Sorting Railway Cars   An infinitely long railway has a train consisting of n cars, numbered from ...

  9. hdu 5427 A problem of sorting 水题

    A problem of sorting Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contest ...

随机推荐

  1. nodejs笔记--与Redis的交互篇(六)

    原文地址:http://www.cnblogs.com/zhongweiv/p/node_redis.html 安装前准备 win64: Install python: http://www.pyth ...

  2. cookie,localstorge,sessionstorge三者总结

    相同点:都是客户端存储东西的: 不同: 1大小,cookie最小;locastorge最大 2 cookie设置好会在header头里面自动带的:但是ls和ss不会:ls同个浏览下不同网页(非跨域)都 ...

  3. IIS7,IIS7.5 URL重写模块工具

    URL 重写模块 2.0 提供基于规则的重写机制,可在 Web 服务器处理请求的 URL 之前对其进行更改,以及在向 HTTP 客户端提供响应内容之前修改响应内容. 注意:使用环境为IIS7.0(x6 ...

  4. C# Dsoframer.ocx 如何在winform中嵌入Excel,内嵌Excel,word

    如果你还不太清楚Dspframer.ocx怎么放到窗体上就看上一篇文章,里面详细介绍了是如何放到窗体上的. 链接:http://www.cnblogs.com/pingming/p/4182045.h ...

  5. 提升MyEclipse运行速度

    修改MyEclipse.ini文件中的,将-vmargs后面的参数修改为 -Xms256m -Xmx768m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:Max ...

  6. 第71天:jQuery基本选择器(二)

    jQuery选择器 一.内容过滤选择器 选择器 描 述 返 回 示 例 :contains(text) 匹配含有文本内容text的元素 集合元素 $(“p:contains(今天)”) :empty ...

  7. [转]matlab中squeeze函数的用法,numel的用法

    squeeze的作用是移除单一维. 如果矩阵哪一个维数是1,B=squeeze(A)就将这个维数移除. 考虑2-by-1-by-3 数组Y = rand(2,1,3). 这个数组有单一维 —就是每页仅 ...

  8. BZOJ 1452 Count(二维树状数组)

    大水题. 建立100个二维树状数组,总复杂度就是O(qlognlogm). # include <cstdio> # include <cstring> # include & ...

  9. POJ1284:Primitive Roots——题解

    http://poj.org/problem?id=1284 给一个奇质数p,求p的原根数量. 有一个结论:当正整数n存在原根时,其一共有phi(phi(n))个不同余的原根. 所以答案为phi(p- ...

  10. BZOJ2005:[Noi2010]能量采集——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2005 Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光 ...