2017暑期ACM俱乐部个人训练赛第2场 G题 Balanced Photo(树状数组求逆序对)



问题 G: Balanced Photo

时间限制: 1 Sec   内存限制: 128 MB
提交: 88   解决: 35

题目描述

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

提示

In this example, the cows of heights 34, 5, and 2 are unbalanced.



题目大意:

一群牛排成一批照相   一头牛   左边比他高的牛的个数为Li    右边比他高的牛的个数为Ri     如果 max(Li,Ri)>min(Li,Ri)*2

那么这头就不平衡    问一共有多少头不平衡的牛


分析:

求一下这头牛左右两边的逆序对    看是否满足关系式 

在求逆序对的过程中需要对原始数据进行离散化      即对原始数据进行放缩且不改变它左右两边的大小关系  



AC代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int infmax=10e5+10;
int N;
int c[infmax];
int temp[infmax];
int li[infmax];
int ri[infmax];
struct node {
    int num;
    int index;
}a[infmax];
bool cmp(node x,node y){
    return x.num<y.num;
}
void add(int k){//     这时更新函数表示i加入序列
    while (k<=N){
        c[k]++;//         插入元素   +1
        k+=k&-k;
    }
}
int read(int k){//          这时求和函数表示  小于等于i的数字的个数
    int sum=0;
    while (k){
        sum+=c[k];
        k-=k&-k;
    }
    return sum;
}
int main (){
    while (scanf ("%d",&N)!=EOF){
        for (int i=1;i<=N;i++){
            scanf ("%d",&a[i].num);
            a[i].index=i;//          标记原始数据的位置
        }
        sort(a+1,a+N+1,cmp);
        for (int i=1;i<=N;i++)
            temp[a[i].index]=i;//      离散化
        memset(c,0,sizeof(c));
        for (int i=1;i<=N;i++){//        左
            add(temp[i]);
            li[i]=i-read(temp[i]);//         左侧大于temp[i]的个数
        }
        memset(c,0,sizeof(c));
        for (int i=N;i>=1;i--){//         右
            add(temp[i]);
            ri[i]=N-i+1-read(temp[i]);

        }
        int ans=0;
        for (int i=1;i<=N;i++){
            if (max(li[i],ri[i])>min(li[i],ri[i])*2)
                ans++;
        }
        printf ("%d\n",ans);
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值