1 条题解

  • 0
    @ 2026-1-28 10:48:24
    #include <bits/stdc++.h>
    using namespace std;
    
    // [1] arr数组-存储每头牛的高度,类型为long long(适配高度≤1e9的范围),最多支持1e6+100个元素
    long long arr[1000100];
    
    int main(){
        // [2] n-牛的总数(n≤1e6)
        int n;
    	cin>>n;  
        // [3] 读取n头牛的高度,存入arr数组(0-based索引)
    	for(int i=0;i<n;i++) cin>>arr[i];
        // [4] s-单调递减栈,存储从右到左遍历过程中,当前牛右侧的牛的高度(栈顶为最近的右侧牛)
    	stack<int> s;
        // [5] v-辅助栈,存储s中对应高度的牛能看到的右侧牛的数量(与s的元素一一对应)
    	stack<int> v;
        // [6] ans-所有牛能看到的牛的数量之和,类型为long long(避免n=1e6时溢出)
    	long long ans=0;
    
        // [7] 逆序遍历(从最右侧的牛到最左侧的牛):因为当前牛的视野仅由右侧的牛决定,逆序处理能复用右侧牛的计算结果
    	for(int i=n-1;i>=0;i--){
            // [8] 情况1:栈为空(当前是最右侧的牛),右侧无牛,能看到0头
    		if(v.empty()){
    			s.push(arr[i]);    // 当前牛的高度入栈
    			v.push(0);         // 当前牛能看到的数量为0,入辅助栈
    		} 
    		else {
                // [9] sum-当前牛能看到的右侧牛的数量,初始化为0
    			long long sum=0;
                // [10] 维护单调递减栈:弹出所有高度小于当前牛的元素(这些牛都能被当前牛看到)
                // 逻辑:当前牛比这些牛高,因此能看到这些牛,以及这些牛能看到的所有牛(所以sum += 1 + v.top())
    			while(!s.empty()&&arr[i]>s.top()){
    				sum=sum+1+v.top();  // 1表示当前弹出的牛,v.top()表示该牛能看到的数量
    				s.pop();
    				v.pop();
    			}
                // [11] 将当前牛的高度和能看到的数量入栈,作为左侧牛的计算依据
    			s.push(arr[i]);
    			v.push(sum);
                // [12] 累加当前牛能看到的数量到总结果
    			ans+=sum;
    		}
    	}
        // [13] 输出所有牛能看到的数量之和
    	cout<<ans;
    	return 0;
    }
    
    • 1

    信息

    ID
    1265
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者