1 条题解
-
0
#include<bits/stdc++.h> using namespace std; // [1] arr数组-存储同学的身高,输入顺序为「队尾→窗口」(最后一个同学到第一个挨着窗口的同学),最多支持80100个元素 long long arr[80100]; int main(){ // [2] n-排队的同学总数(输入的正整数) int n; cin>>n; // [3] 读取n个同学的身高,按「队尾→窗口」的顺序存入arr数组 for(int i=0;i<n;i++) cin>>arr[i]; // [4] s-单调递减栈,存储从窗口到当前同学的身高(保证栈内身高递减,栈顶为当前同学前面最近的、身高≥当前同学的人) stack<long long> s; // [5] v-辅助栈,存储s中对应身高的同学能看到的人数(与s的元素一一对应,实现复用前面同学的计算结果) stack<long long> v; // [6] sum-所有同学能看到的人数之和,类型为long long避免n较大时溢出 long long sum=0; // [7] 逆序遍历(从窗口前的第一个同学,到队尾的同学):因为每个同学的视野仅由「窗口方向(前面)」的同学决定,逆序处理可复用已计算的结果 for(int i=n-1;i>=0;i--){ // [8] 情况1:栈为空(当前是窗口前的第一个同学,前面无同学) if(s.empty()){ s.push(arr[i]); // 当前同学的身高入栈 v.push(0); // 前面无同学,能看到0人,入辅助栈 } else{ // [9] count-当前同学能看到的人数,初始化为0 int count=0; // [10] 维护单调递减栈:弹出所有身高小于当前同学的元素(这些同学都能被当前同学看到) // 逻辑:当前同学比这些同学高,因此能看到这些同学,以及这些同学能看到的人数(count += 1 + v.top(),1表示当前弹出的同学,v.top()表示该同学能看到的人数) while(!s.empty() && arr[i]>s.top()){ count=count+1+v.top(); s.pop(); v.pop(); } // [11] 将当前同学的身高和能看到的人数入栈,作为后续同学(队尾方向)的计算依据 s.push(arr[i]); v.push(count); // [12] 累加当前同学能看到的人数到总结果 sum+=v.top(); } } // [13] 输出所有同学能看到的人数之和 cout<<sum; return 0; }
- 1
信息
- ID
- 1264
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者