今天刷了道栈算法的题目,然后理解了c++中一些与栈相关的函数。它需要头文件#include<stack>
用法如下:
stack<int> S;//声明一个对象
S.empty();//栈空返回true 否则false
int x=S.size();//返回栈中元素个数于x
S.pop();//移除栈顶元素
S.push(x);将x置于栈顶
x=S.top();返回栈顶元素
文章转载于:https://blog.youkuaiyun.com/qq_24286723/article/details/50037479?locationNum=1&fps=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(没有用栈,时间超过2000ms)
#include<stdio.h>
#define N 1000000
int a[N]={0};
int main()
{
long long int n,i=0,r=0,c,z=0;
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld",&a[i]);
for(i=0;i<n-1;i++)
{
c=a[i+1];
if(a[i]>c)
z++;
for(r=i+1;r<n;r++)
{
if(a[i]>a[r])
{
if(c<a[r])
z++;
else
c=a[r];
}
if(a[i]<=a[r])
c=a[r];
}
}
printf("%lld",z);
return 0;
}
代码2(用了栈,时间超了):
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
int sum;
struct node*next;
}node;
typedef struct Zhan
{
node*top;
int g;
}zhan;
void csh(zhan *pzhan)
{
pzhan->top=NULL;
pzhan->g=0;
}
void push(zhan *pzhan,int sum)
{
node*news=(node*)malloc(sizeof(node));
news->sum=sum;
news->next=pzhan->top;
pzhan->top=news;
pzhan->g++;
}
void pop(zhan *pzhan)
{
node *poped=pzhan->top;
pzhan->top=pzhan->top->next;
pzhan->g--;
free(poped);
}
int main()
{
int i,n;
zhan zhan;
csh(&zhan);
long long z=0,c=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lld",&c);
while(zhan.top!=NULL && (zhan.top->sum)<=c)
pop(&zhan);
z=z+zhan.g;
push(&zhan,c);
}
printf("%lld\n",z);
return 0;
}
代码3(我用了c++中的函数,最方便!!):
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<stack>
using namespace std;
stack<long long>zhan;
int main()
{
int i,n;
long long z=0,c=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%lld",&c);
while(!zhan.empty() && (zhan.top())<=c)
zhan.pop();
z=z+zhan.size();
zhan.push(c);
}
printf("%lld\n",z);
return 0;
}
思路:从前往后栈,按顺序进入一个身高值,将栈中 小于(或等于)该身高的数据弹出,栈中剩下的元素对应的牛都能看见该身高的牛。算出num后入栈该身高。可以计算出,每只奶牛能被他前面的多少只奶牛看到自己的发型,就反向得到了奶牛看到的发型总和
还有一题:
羊羊们到了谈婚论嫁的年龄了,雷巨巨有的忙了。他有四种羊,每种羊分公母且公母才能配对,为方便输入用[]<>(){}代替四种羊,一天他让一些羊羊站成一排开始配对,有如下定义:假设s1和s2是满足配对的,则s2,{s1}s2,[s1]s2,(s1)s2也是满足配对的,如"[[(){}]<>]"和"{[(<>)]}"是满足配对的,而"<)()"和"]><["是不满足的,雷巨巨可以选择让其中一种羊变成另一种羊但无法改变其性别,如'<'可以变成'(','{','['但不可变成')','}',']'。问至少改变几次才能让羊羊们都找到幸福。
Input
输入一行字符串,仅由四种括号组成,长度不超过1e6
Output
如果不能使所有羊羊配对,则打印"Impossible",否则,打印最少替换的次数
Examples
Input
[<}){}
Output
2
Input
{()}[]
Output
0
Input
]]
Output
Impossible
这题我直接暴力了:
#include<stdio.h>
#include<string.h>
#define N 1000000
int main()
{
char a[N],b[N];
gets(a);
int n,i,r=0,z=0,t;
n=strlen(a);
for(i=0;i<n;i++)
{
if(a[i]=='['||a[i]=='{'||a[i]=='('||a[i]=='<')
{
b[r]=a[i];
r++;
}
if(a[i]==']'||a[i]=='}'||a[i]==')'||a[i]=='>')
{
switch(b[r-1])
{
case '(':if(a[i]!=')')z++;break;
case '{':if(a[i]!='}')z++;break;
case '<':if(a[i]!='>')z++;break;
case '[':if(a[i]!=']')z++;break;
}
r--;
if(r<0)
break;
}
}
if(r!=0)
printf("Impossible");
else
printf("%d",z);
return 0;
}
今天任务算是达到了,找机会总结一下动态规划和双指针,把我的推箱子美好一下。
先睡了。