G - Radar Scanner Gym - 102220G(中位数~~)

zThere are n rectangle radar scanners on the ground. The sides of them are all paralleled to the axes. The i-th scanner's bottom left corner is square (ai,bi) and its top right corner is square (ci,di)

. Each scanner covers some squares on the ground.

You can move these scanners for many times. In each step, you can choose a scanner and move it one square to the left, right, upward or downward.

Today, the radar system is facing a critical low-power problem. You need to move these scanners such that there exists a square covered by all scanners.

Your task is to minimize the number of move operations to achieve the goal.

Input

The first line of the input contains an integer T(1T1000)

, denoting the number of test cases.

In each test case, there is one integer n(1n100000)

in the first line, denoting the number of radar scanners.

For the next n

lines, each line contains four integers ai,bi,ci,di(1ai,bi,ci,di109,aici,bidi)

, denoting each radar scanner.

It is guaranteed that n106

.

Output

For each test case, print a single line containing an integer, denoting the minimum number of steps.

Example
Input
1
2
2 2 3 3
4 4 5 5
Output
2


题解:由于横纵方向地位相同,我们不妨来看横方向,题目要找一点x使得n条线段经过平移最少次数,至少重合一点。
假设那一点就为x,那么一条线段至少与x有交点的话,所需距离为:d=(|l-x|+|r-x|-|r-l|)/2,纸上画一遍即可。我们要找的是所有线段移动的距离之和最小,那么只需Σd最小,
由于d中的|r-l|为常数,所以我们只需要求Σ(|l-x|+|r-x|)最小,那么x就是所有l,r的中位数了~~。题目难得就是转化~~
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<stdio.h>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int maxn=100010;
struct node
{
    ll l,r;
}q[maxn],w[maxn];
ll n,a[maxn*2];
ll ok(node q[])
{
    int top=0;
    for(int i=1;i<=n;i++){
        a[++top]=q[i].l;
        a[++top]=q[i].r;
    }
    sort(a+1,a+1+top);
    ll x=(a[top/2]+a[top/2+1])/2;
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans+=(abs(q[i].l-x)+abs(q[i].r-x)-(q[i].r-q[i].l))/2;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    int T;
    cin>>T;
    while(T--){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>q[i].l>>w[i].l>>q[i].r>>w[i].r;
        }
        ll ans=0;
        ans+=ok(q);
        ans+=ok(w);
        cout<<ans<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/cherish-lin/p/11065112.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值