1 条题解
-
0
按题意模拟
#include <bits/stdc++.h> using namespace std; int n, a[100000 + 5]; int cnt; // 记录有几个栈 int dd[100000 + 5]; // 每个栈的最底部元素 stack<int> sta[100000 + 5]; // 右边的栈们 int now; // 已经拿走的盘子的最大值 int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; cnt = 1; sta[cnt].push(a[1]); dd[cnt] = a[1]; now = 0; // 右边还没拿过东西,所有比 0 大的都能拿 for (int i = 2; i <= n; i++) { if (a[i] < now) { cout << i - 1; return 0; } // 找到 a[i] 该放在哪个栈上面 int pos = -1; for (int j = 1; j <= cnt; j++) if (dd[j] > a[i]) { pos = j; break; } // 看看要不要新开一个栈 if (pos == -1) { cnt++; sta[cnt].push(a[i]); dd[cnt] = a[i]; continue; } // 把 sta[pos] 的顶端比它小的拿走 while (sta[pos].top() < a[i]) { now = sta[pos].top(); sta[pos].pop(); } sta[pos].push(a[i]); } cout << n; return 0; }
使用二分快速定位应该放的位置
#include <bits/stdc++.h> using namespace std; int n, a[100000 + 5]; int cnt; // 记录有几个栈 int dd[100000 + 5]; // 每个栈的最底部元素 stack<int> sta[100000 + 5]; // 右边的栈们 int now; // 已经拿走的盘子的最大值 int main() { cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; cnt = 1; sta[cnt].push(a[1]); dd[cnt] = a[1]; now = 0; // 右边还没拿过东西,所有比 0 大的都能拿 for (int i = 2; i <= n; i++) { if (a[i] < now) { cout << i - 1; return 0; } // 找到 a[i] 该放在哪个栈上面 int pos = upper_bound(dd + 1, dd + cnt + 1, a[i]) - dd; // 看看要不要新开一个栈 if (pos == cnt + 1) { cnt++; sta[cnt].push(a[i]); dd[cnt] = a[i]; continue; } // 把 sta[pos] 的顶端比它小的拿走 while (sta[pos].top() < a[i]) { now = sta[pos].top(); sta[pos].pop(); } sta[pos].push(a[i]); } cout << n; return 0; }
- 1
信息
- ID
- 5977
- 时间
- 2000ms
- 内存
- 250MiB
- 难度
- 3
- 标签
- 递交数
- 6
- 已通过
- 4
- 上传者