NC53255. 有趣的家庭菜园
描述
输入描述
第一行一个正整数N,代表田地被分为了N个区域。
接下来N行,第i行一个整数,表示第i株植物在春天时的高度。
输出描述
输出一行一个整数,表示最少需要的操作次数。
示例1
输入:
6 2 8 4 5 3 6
输出:
3
说明:
示例2
输入:
5 4 4 2 4 4
输出:
2
说明:
将第3株IOI草移动到区域1或区域5。示例3
输入:
4 1 3 4 2
输出:
0
C++11(clang++ 3.9) 解法, 执行用时: 117ms, 内存消耗: 3888K, 提交时间: 2020-08-11 21:30:39
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long const int maxn=300010; int n; struct node{int h,id;}a[maxn]; bool cmp(node x,node y){return x.h>y.h;} int s[maxn]; void add(int x,int y){for(int i=x;i<=n;i+=(i&-i))s[i]+=y;} int getsum(int x){int re=0;for(int i=x;i;i-=(i&-i))re+=s[i];return re;} int main() { LL ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i].h); a[i].id=i; } sort(a+1,a+1+n,cmp); a[0].h=-1; // for(int i=1;i<=n;i++) // printf("%d %d %d\n",i,a[i].h,a[i].id); int ii=1; for(int i=1;i<=n;i++) { if(a[i].h!=a[i-1].h){while(ii<i)add(a[ii++].id,1);} int t=getsum(a[i].id); ans+=(LL)(min(ii-1-t,t)); } printf("%lld",ans); }