今天就刷了两个题,尝试了一个题,
主要看了单调栈,
单调栈分为两种一中是栈中元素从栈顶到栈顶呈从小到大的排序的栈这样的栈称为单调递增栈
另一种从栈顶到栈底数据从大到小称为单调递减栈
单调栈的应用一般可以用来求这样两类问题
1.视野总和问题
就是下面的这个问题
Farmer John的奶牛在风中凌乱了它们的发型……
每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80,000)。对于奶牛i来说,如果奶牛i+1,i+2,……,N这些奶牛的身高严格小于奶牛i,则奶牛i可以看到它们凌乱的发型。
比如下面这个例子:
* * * * = *
= * * * = *
= * - * = * 奶牛面向这边-->
= * = * = *
= - = = = *
= = = = = =
1 2 3 4 5 6
('*'表示空的,这是译者为了格式特意弄的,原题没有)
令ci表示第i只奶牛能够看到的发型数量,请计算c1 + c2 + c3 + … + cN的值
对于上面这个例子,答案为3 + 0 + 1 + 0 + 1 + 0=5。
输入
第一行:奶牛数量N
第二到N+1行:第i+1行输入奶牛i的身高
输出
第一行:一个整数即c1到cN的和
样例输入
6
10
3
7
4
12
2
样例输出
5
解题思路是
观察题之后,我们发现实际上题目转化为找当前数字向右查找的第一个大于他的数字之间有多少个数字,然后将每个结果累计就是答案,我们使用单调栈来解决这个问题。
1.设置一个单调递增的栈(栈内0~n为单调递减)
2.当遇到大于栈顶的元素,开始更新之前不高于当前人所能看到的值
附上代码
#include<stdio.h>
int main()
{
int n;
long long a[80005];//用来接收输入数字的数组,根据题目要求必须是longlong形的
long long stack[80005];//自定义堆栈
int i;
int top=0;//栈内元素.
long long sum=0;//用来累加结果的
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<=n;i++)
{
if(top==0||a[stack[top]]>a[i])//如果栈为空或者入栈元素大于栈顶元素则入栈
stack[++top]=i;//用下标来储存数据
else
if(a[stack[top]]<=a[i])//如果栈顶元素小于或者等于入栈元素则出栈
{
while(a[stack[top]]<=a[i]&&top!=0)
{
sum+=i-1-stack[top];
top--;
}
stack[++top]=i;//入栈。
}
}
for(i=1;i<top;i++)//剩下栈内元素可以看到多少人要一起加,
sum=sum+n-stack[i];
printf("%lld",sum);
}
明天要团建啊,好烦感觉心思有点动摇了,因为我觉得理解起来好抽象的哦
咬咬牙坚持住吧