码迷,mamicode.com
首页 > 其他好文 > 详细

解题报告 之 CodeForces 91B Queue

时间:2015-06-01 22:52:50      阅读:292      评论:0      收藏:0      [点我收藏+]

标签:codeforces 91b   queue   单调栈   acm   数据结构   

解题报告 之 CodeForces 91B Queue


Description

There are n walruses standing in a queue in an airport. They are numbered starting from the queue‘s tail: the 1-st walrus stands at the end of the queue and the n-th walrus stands at the beginning of the queue. The i-th walrus has the age equal to ai.

The i-th walrus becomes displeased if there‘s a younger walrus standing in front of him, that is, if exists such j (i?<?j), that ai?>?aj. Thedispleasure of the i-th walrus is equal to the number of walruses between him and the furthest walrus ahead of him, which is younger than thei-th one. That is, the further that young walrus stands from him, the stronger the displeasure is.

The airport manager asked you to count for each of n walruses in the queue his displeasure.

Input

The first line contains an integer n (2?≤?n?≤?105) — the number of walruses in the queue. The second line contains integers ai (1?≤?ai?≤?109).

Note that some walruses can have the same age but for the displeasure to emerge the walrus that is closer to the head of the queue needs to bestrictly younger than the other one.

Output

Print n numbers: if the i-th walrus is pleased with everything, print "-1" (without the quotes). Otherwise, print the i-th walrus‘s displeasure: the number of other walruses that stand between him and the furthest from him younger walrus.

Sample Input

Input
6
10 8 5 3 50 45
Output
2 1 0 -1 0 -1 
Input
7
10 4 6 3 2 8 15
Output
4 2 1 0 -1 -1 -1 
Input
5
10 3 1 10 11
Output
1 0 -1 -1 -1 

题目大意:有一个排队,右边的队头,左边的是队尾。给出每个排队者的年龄,年龄大的并不满意有更年轻的排在前面,所以很不满意。一个海象的不满意度是 排它前面比它年轻的所有海象中离它的最远的那个与它的距离-1。求出所有海狮的不满意度,如果前面没有更年轻的输出-1。

分析:我们设一只海象前面最远的年轻海象位置为right。我们考虑DP的思想,如果年龄为 i 的海象的right求出,那么年龄为 i+1的海象优先考虑以 i 的right作为它自己的right,因为如果 i 的right 都在i+1的左边,则剩下的更不可能在其右边。如果不满足 i 的right在i+1右边,那么只能说明i+1右边没有更年轻的,否则这个更年轻的会 i 的right,所以right设置为 i+1 它自己的位置。

一旦一个海狮的位置和最右都确定了,则直接算出来即可。注意要按照age排序而不是pos。

上代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 10;

struct W
{
	int age, pos, right;
	bool operator<(const W& rhs)const
	{
		if(age != rhs.age)return age < rhs.age;
		return pos < rhs.pos;
	}
};

W w[MAXN];
int disp[MAXN];

int main()
{
	int n;
	while(scanf( "%d", &n ) == 1)
	{
		for(int i = 1; i <= n; i++)
		{
			scanf( "%d", &w[i].age );
			w[i].pos = w[i].right = i;
		}

		sort( w + 1, w + n + 1 );

		disp[w[1].pos] = - 1;
		for(int i = 2; i <= n; i++)
		{
			if(w[i - 1].right > w[i].pos)
			{
				w[i].right = w[i - 1].right;
			}
			disp[w[i].pos] = w[i].right - w[i].pos - 1;
		}

		for(int i = 1; i < n; i++)
			printf( "%d ", disp[i] );
		printf( "%d\n", disp[n] );
	}
	return 0;
}

其实也有单调队列的方法,我觉得比较难理解,大概思路。队列从排队最前端,依次只插入比队尾小元素,以保持单调递减(因为如果比前面的数大,那么最远的那个肯定不会是当前这个,所以当前这个插入了队列也没用)。对于一个大于队列尾的海象,用lower_bound去找比它小的且最靠近的海象,然后用位置一减即可。

上代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#define MAX 100002
using namespace std;

int a[MAX],ans[MAX];
vector<int> v,num;

int main()
{
    int n;
    //freopen("data.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        v.clear();
        num.clear();
        for(int i=n-1;i>=0;i--){
            if(v.size()==0 || v.back()>=a[i]){
                v.push_back(a[i]); num.push_back(i);
                ans[i]=-1;
            }else{
                int j = (lower_bound(v.rbegin(),v.rend(),a[i]) - v.rbegin());
                j = (int)v.size() - j - 1;
                ans[i] = num[j+1] - i - 1;
            }
        }
        for(int i=0;i<n;i++){
            if(i) printf(" ");
            printf("%d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}


啦啦啦啦啦啦啊,继续加油!

解题报告 之 CodeForces 91B Queue

标签:codeforces 91b   queue   单调栈   acm   数据结构   

原文地址:http://blog.csdn.net/maxichu/article/details/46313919

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!