17暑期ACM俱乐部个人训练赛第2场 G Balanced Photo (树状数组)



问题 G: Balanced Photo

时间限制: 1 Sec   内存限制: 128 MB
提交: 89   解决: 36
[ 提交][ 状态][ 讨论版]

题目描述

Farmer John is arranging his N cows in a line to take a photo (1N100,000). The height of the ith cow in sequence ishi, and the heights of all cows are distinct. 
As with all photographs of his cows, FJ wants this one to come out looking as nice as possible. He decides that cow i looks "unbalanced" if Li and Ri differ by more than factor of 2, where Li and Ri are the number of cows taller than i on her left and right, respectively. That is, i is unbalanced if the larger of Li and Ri is strictly more than twice the smaller of these two numbers. FJ is hoping that not too many of his cows are unbalanced.

Please help FJ compute the total number of unbalanced cows.

输入

The first line of input contains  N . The next  N  lines contain  h1hN , each a nonnegative integer at most 1,000,000,000.

输出

Please output a count of the number of cows that are unbalanced.

样例输入

7

34

6

23
0

5

99

2

样例输出

3

题意:  一排牛 照相,   对于某一头牛x  如果左边比他高的个数 记为le[x]  右边比他高的个数为 ri[x]   如果max(le[x],ri[x])>min(le[x].ri[x])*2 

则这头牛 即为不平衡,  问这样的牛有多少头


先把牛的身高离散成等差1的序列;

用树状数组, 把所有n 的 左边和右边 描述出来,  最后找符合的个数


#include <stdio.h>
#include <queue>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=101000;
int tree[N];
int a[N];
int n;
int le[N],ri[N];
struct node{
	int x,idex;
}pre[N];;
int cmp(node a,node b)
{
	if(a.x==b.x)
		return a.idex<b.idex;
	return a.x<b.x;
}
void add(int k,int num)
{
	while(k<=n)
	{
		tree[k]+=num;
		k+=k&-k;
	}
}
int Sum(int k)
{
	int sum=0;
	while(k)
	{
		sum+=tree[k];
		k-=k&-k;
	}
	return sum;
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&pre[i].x);
			pre[i].idex=i;
		}
		sort(pre+1,pre+n+1,cmp);
		for(int i=1;i<=n;i++)// 离散化成数字; 
			a[pre[i].idex]=i;
		memset(tree,0,sizeof(tree));
		for(int i=1;i<=n;i++)// 找左边比它大的数 
		{
			add(a[i],1);
			le[i]=i-Sum(a[i]);
		}
		memset(tree,0,sizeof(tree));
		for(int i=n;i>=1;i--)// 右边 
		{
			add(a[i],1);
			ri[i]=n-i+1-Sum(a[i]);
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			if(max(le[i],ri[i])>2*min(le[i],ri[i]))
				ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}


转载于:https://www.cnblogs.com/sizaif/p/9078514.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值