alg2025/src/8/7/807stack.cpp
2025-08-07 12:53:24 +08:00

65 lines
1.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <vector>
#include <numeric>
// 使用标准 OI/ACM 风格的快速 I/O
void setup_io() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
}
// 解决单次测试数据的函数
void solve() {
int n;
std::cin >> n;
// pos 数组用于存储每个数字 1...n 在输入排列 a 中的位置(从 1 开始计数)
// 大小为 n+1 是为了方便使用 1-based 索引,即 pos[v] = i
std::vector<int> pos(n + 1);
for (int i = 1; i <= n; ++i) {
int val;
std::cin >> val;
pos[val] = i;
}
// 如果 n <= 1答案就是 n
if (n <= 1) {
std::cout << n << "\n";
return;
}
// 至少需要一个栈
int m = 1;
// 遍历数字 2 到 n检查相邻数字 i-1 和 i 是否可以放在同一个栈中
for (int i = 2; i <= n; ++i) {
// [核心逻辑]
// 为了让一个栈能够依次弹出 s, s+1, ..., t这些数字在入栈时必须以逆序 t, t-1, ..., s 进入。
// 这意味着在原始排列 a 中t 必须在 t-1 之前t-1 必须在 t-2 之前,以此类推。
// 即 pos[t] < pos[t-1] < pos[t-2] < ... < pos[s]。
//
// 应用到相邻数字 i-1 和 i如果它们想在同一个栈中必须满足 pos[i] < pos[i-1]。
// 如果 pos[i-1] < pos[i],这表示 i-1 在 i 之前出现,它们不能放入同一个栈。
// 这时i-1 是上一个数字段的末尾,而 i 是一个新的数字段的开始。
// 因此,我们必须启用一个新的栈。
if (pos[i - 1] < pos[i]) {
m++;
}
}
std::cout << m << "\n";
}
int main() {
setup_io();
// 多组测试数据
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}