我好像不会做


我好像不会做


浙江理工大学月赛
题目描述
plw现在在一个仓库里当搬砖工,这个仓库存放的是n种不同颜色的砖块,颜色编号从1-n。plw突然兴起想堆一个墙,为了美观,plw决定按照1-n的颜色编号顺序从下往上垒成一列。
有一个传送带和仓库相连,传送带按照 a[1] a[2] … a[n] 的颜色顺序源源不断的送砖进来。
如果当前送进来的砖恰好是plw所需要的, plw就会把这个砖垒进墙内。否则plw就把这个砖放进一旁的次元栈里面,次元栈可以存放无数个砖。
每次plw新垒上一个砖后,他会看看次元栈的顶部的砖是不是所需要的(如果次元栈中有砖),如果是他就会从次元栈中取出这个砖,并且垒上去。
如果plw没办法得到想要的砖,plw就会开启传送带,传送带会送入下一个砖。
plw想知道他需要至少启动多少次传送带,才能完成目标。
启动一次传送带会送入一块砖。
PS:
假定plw无限高,身高为 INF.

输入

n <= 1e5
a[1] ... a[n]1-n的排列。

输出

输出一个数,为需要多少个砖块。

样例输入

12
8 9 10 6 5 7 11 3 4 1 2 12

样例输出

48

源代码:

#include<bits/stdc++.h>
using namespace std;
int n,i,j;
long long a[100100],l[100100],r[100100],b[100100],top[100100],ans=0,sum=0;
int main() {
	scanf("%d",&n);
	for(i=1; i<=n; i++) {
		scanf("%lld",&a[i]);
		l[i]=i-1;
		r[i]=i+1;
		b[a[i]]=i;
	}
	for(i=1; i<=n; i++) {
		if(top[i]==0) {
			sum=i;
			ans++;
			for(j=b[i]; j<=n; j=b[sum]) {
				l[j]=j-1;
				r[j]=j+1;
				top[sum]=1;
				sum++;
				while(a[l[j]]==sum||a[r[j]]==sum) {
					if(a[l[j]]==sum) {
						l[j]--;
						top[sum]=1;
						sum++;
					} else {
						r[j]++;
						top[sum]=1;
						sum++;
					}
				}
				if(b[sum]<r[j]) {
					break;
				}
			}
		}
	}
	cout<<ans*n-n+b[n]<<endl;
	return 0;
}

AC


发布了50 篇原创文章 · 获赞 51 · 访问量 1422

猜你喜欢

转载自blog.csdn.net/m0_45682806/article/details/103333693