原更新日期:2018-12-08 18:06:40
很明显是栈了好吧
题目大意
给定 (n) 本书,序号分别为(1)到(n),现在执行(n)个操作, 第(i)个操作需要从栈内取出编号为(b_i)的书,如果该书已经取出,则输出(0)否则将该书从栈内取出,同时取出在栈内比(b_i)靠上的书,并且输出一共取出了几本书
输入输出格式
输入格式
The first line contains one integer (n~(1 le n le 2 cdot 10^5)) — the number of books in the stack.
The second line contains (n) integers (a_1, a_2, dots, a_n~(1 le a_i le n)) denoting the stack of books.
The third line contains n n integers (b_1, b_2, dots, b_n~(1 le b_i le n)) denoting the steps Vasya is going to perform.
All numbers (a_1 dots a_n) are distinct, the same goes for (b_1 dots b_n) .
输出格式
Print (n) integers. The (i) -th of them should be equal to the number of books Vasya moves to his backpack during the (i) -th step.
输入输出样例
#1
3
1 2 3
2 1 3
2 0 1
#2
5
3 1 4 2 5
4 5 1 3 2
3 2 0 0 0
#3
6
6 5 4 3 2 1
6 5 3 4 2 1
1 1 2 0 1 1
解析
本文同步发布于洛谷博客
粗略看了一下 貌似没人和我的解法相同
那就来写一发题解吧
在读入的时候 我们用另一个数组lead[i]
来存编号为i
的书在读入的数组book[]
的下标
这样我们在检测读入的书是否被取出时就不用遍历一遍book[]
弹出书本的时候,我们首先看一下这个书本是否被取出
如果是就直接输出0
否则就开始弹出书本
我们用一个变量now = 0
记录当前弹出了几个书本,用一个数组vis[i]
记录第i
本书是否被弹出
在弹出之前,用一个变量orin
记录一下还没更新的now
接着在每次弹出的时候更新vis[++now]
为真,直到遇到当前要弹出的书本编号
最后orin - now
即为答案
代码实现:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <stack>
using std::cin;
using std::cout;
using std::endl;
using std::string;
const int MAXN = 2e5 + 10;
int n;
int book[MAXN];
int lead[MAXN];
bool vis[MAXN];
int now = 0;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", book + i);
lead[book[i]] = i;
// 让lead[]作为book[]的索引,查找的时候快一些
}
for (int i = 1; i <= n; ++i) {
int o;
scanf("%d", &o);
if (vis[lead[o]]) printf("0 ");
// 被弹过了,输出0
else {
int orin = now;
while (book[++now] != o) {
vis[now] = true;
// 循环更新vis(弹出书本)
}
vis[now] = true;
printf("%d ", now - orin);
}
}
return 0;
}
总感觉自己的代码能被 Hack