一种消息接收并打印的结构设计
题目描述
已知一个消息流会不断地吐出整数 1 ∼ N 1 \sim N 1∼N,但不一定按照顺序吐出。如果上次打印的数为i,那么当i+1出现时,请打印i+1及其之后接收过的并且连续的所有数,直到 1 ∼ N 1 \sim N 1∼N全部接收并打印完,请设计这种接收并打印的结构
[要求]
消息流最终会吐出全部的 1 ∼ N 1 \sim N 1∼N,当然最终也会打印完所有的 1 ∼ N 1\sim N 1∼N,要求接收和打印 1 ∼ N 1 \sim N 1∼N的整个过程,时间复杂度为O(N)$。
输入描述:
第一行一个整数N。
接下来一行有N个整数。保证输入是一个1到N的排列
输出描述:
输出N行,每行两个数。
为了检验输出的正确性,请在输出当前打印的数字之后输出此时最后一个加入的元素。
具体看输入输出样例
示例1
输入
9
2 1 4 5 7 3 9 8 6
输出
1 1
2 1
3 3
4 3
5 3
6 6
7 6
8 6
9 6
说明
消息流吐出2,一种结构接收而不打印2,因为1还没出现。
消息流吐出1,一种结构接收1,并且打印:1, 2。
消息流吐出4,一种结构接收而不打印4,因为3还没出现。
消息流吐出5,一种结构接收而不打印5,因为3还没出现。
消息流吐出7,一种结构接收而不打印7,因为3还没出现。
消息流吐出3,一种结构接收3,并且打印:3, 4, 5。
消息流吐出9,一种结构接收而不打印9,因为6还没出现。
消息流吐出8,一种结构接收而不打印8,因为6还没出现。
消息流吐出6,一种结构接收6,并且打印:6, 7, 8, 9。
备注:
1
⩽
N
⩽
1
0
5
1 \leqslant N \leqslant 10^5
1⩽N⩽105
保证输入的是一个
1
∼
N
1 \sim N
1∼N的排列
题解:
在读入信息流过程中,使用一个标记 now 记录当前应该打印哪个数字, now 从1 开始,若信息流中的读入元素等于 now ,则可以打印。同时,使用一个哈希表,记录 now 之前哪些数字已经出现,这样的话,在打印 now 之后,循环打印前面出现的 now+1 、now+2等元素。
代码:
#include <cstdio>
using namespace std;
const int N = 100001;
bool vis[N];
int main(void) {
int n, x;
scanf("%d", &n);
int now = 1;
for ( int i = 0; i < n; ++i ) {
scanf("%d", &x);
if ( x == now ) {
printf("%d %d\n", now, now );
int t = now + 1;
while ( t <= n && vis[t] ) printf("%d %d\n", t++, now );
now = t;
if ( now > n ) break;
} else vis[x] = true;
}
return 0;
}