A famous city

城市-HDU4252

题目链接:[Problem - 4252 (hdu.edu.cn)]()

思路:

一栋房子可能延申多列,导致数量不太好算。

可以维护一个从栈顶到栈底单调递减的栈来实现计数。

因为从第二列开始向后操作,如果i比i-1要高那么第i列就不可能和第i-1列是同一幢建筑。

反之,如果i比i-1要来的或者相等,那么就有向前延申的可能,既然有可能,那么就向前找。这是i前面所有比i高的都不可能和i是同一幢(这里需要仔细想想,整个样例模拟一下)

例子:

1=> 栈空,1入栈

2=> 2大于栈顶的1,2入栈

3=> 1小于栈顶的2,2弹栈,ans++,1等于栈顶的1,栈中1弹栈,又因为1==1,ans不计 数,新1入栈

4=> 4大于栈顶的1,入栈

5=> 2小于栈顶的4,4弹栈,ans++

6=> 最后全部弹栈 ans+2,得到答案4 。最后不用特意写一个弹空栈,只要让0压栈就行,根据 之前的弹栈规则会直接清空栈并计数。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int N = 1e5+50;
using namespace std;
int n,cas;
int a[N],stk[N];

void solve(){
	int ans=0,p=0;
	rep(i,1,n+1){//n+1位是0,表示最后让0压栈 
		while(p && a[i]<=stk[p]){
			if(a[i] != stk[p])ans++;
			p--;
		}
		stk[++p]=a[i];
	}printf("Case %d: %d\n",++cas,ans);
}

int main(){
	while(scanf("%d",&n)!=EOF){
		memset(a,0,sizeof a);
		memset(stk,0,sizeof stk);
		rep(i,1,n)scanf("%d",&a[i]);
		solve();
	}
}
posted @ 2021-08-08 22:42  tyrii  阅读(62)  评论(0)    收藏  举报