每日一题:奶牛排队
题目链接:https://www.luogu.com.cn/problem/P6510
题目描述:
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛A是最矮的,最右边的B是最高的,且B奶牛高于A奶牛。中间如果存在奶牛,则身高不能和A,B奶牛相同。问这样的奶牛最多会有多少头?
输入:第一行一个正整数N表示奶牛的头数。
输出:一行一个整数,表示最多奶牛数。
解题思路:我们要找到从后向前数第二个后缀最大值的位置k,A一定在该位置的右侧。并且只要A在k右侧,A是当前序列的后缀最小值,那么A就是一个正确的左端点。
具体代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define NO cout<<"NO"<<endl;
#define YES cout<<"YES"<<endl;
ll NUM=1e9+2;
const int maxn = 100005;
int n, ans, tx, tn;
int a[maxn], sx[maxn], sn[maxn];
int main() {
scanf("%d", &n);
for (int i=1;i<=n;++i) scanf("%d",a+i);
for (int i=1;i<=n;++i) {
while (tn && a[sn[tn]] >= a[i]) --tn;
////保持 sn 数组的元素所对应的 a 数组元素呈现单调递减的性质
while (tx && a[sx[tx]] < a[i]) --tx;
////保持 sx 数组的元素所对应的 a 数组元素呈现单调递增的性质
int k = upper_bound(sn+1, sn+1+tn, sx[tx])-sn;
////在[sn+1,sn+1+tn)区间中查找第一个大于 sx[tx] 的元素并计算长度
if (k!=(tn+1)) {
ans=max(ans, i - sn[k] + 1);
////就更新 ans 成为最大值;
}
sn[++tn]=i;
//// 将当前元素索引存储到 sn 数组中
sx[++tx]=i;
}//// 将当前元素索引存储到 sx 数组中
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具