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();
}
}

浙公网安备 33010602011771号