4925: 城市规划

Description

最近比特镇正在迅速建成。沿着美丽的大街,一座座新建筑拔地而起。小Q喜欢沿着大街走,但问题是不同的建筑位于街对面。为了从一个建筑到另一个建筑,有时需要通过漫长的步行穿过最近的人行道。所以他决定写一个程序,计算如何沿着大街平移所有人行道,使得人行道的布局最有利于行人。他希望尽可能多的人行道出现在某些建筑物的前面,同时人行道的移动距离应当是最小的。
大街以直线表示,人行道被视为这条线上的点。所有建筑物都平行于大街,所以你可以认为它们是直线上的一条条线段。每条线段都具有左边界和右边界。如果某人行道位于某建筑物的左右边界之间(包括边界点),则你可以认为该人行道位于该建筑物的前方。由于人行道已经按照某些标准建立,小Q决定保持它们之间的距离,所以他想将所有的人行道移动相同的距离。
请帮助小Q写一个程序计算最优布局
Input

第一行包含两个正整数n,m(1<=n<=10000,1<=m<=1000),分别表示人行道和建筑的个数。
第二行包含n个整数a_i(0<=a_i<=10^6),分别表示每条人行道的坐标,可能存在两条人行道重合。
接下来m行,每行两个整数l_i,r_i(0<=l_i

感想

感觉最近整个人都变水了。。这么简单的题都没有做出来

题解

首先先将建筑合并,使得人行道不会同时在两个建筑里面
对于每一个人行道,枚举一下每一个建筑,对于一个每个建筑的l,r,我们可以得出这个人行道在他们里面的话移动的范围要满足什么要求。。
就相当于这个范围++
然后这个要是想用线段树应该也可以。。套个log,看着时间应该没有大问题
但是其实我们只需要差分一下就好了
挺好懂的。。
看看代码吧

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=10005;
int a[N];
int n,m;
struct qq
{
    int l,r;
}s[N];
bool cmp (qq a,qq b)
{
    return a.l==b.l?a.r<b.r:a.l<b.l;
}
int tot=1;
const int M=1000005;
int c[M*2];
int P (int x){return x+M;}
int main()
{
    scanf("%d%d",&n,&m);
    for (int u=1;u<=n;u++)  scanf("%d",&a[u]);
    for (int u=1;u<=m;u++)
        scanf("%d%d",&s[u].l,&s[u].r);
    sort(s+1,s+1+m,cmp);
    for (int u=2;u<=m;u++)
    {
        if (s[u].l<=s[tot].r)
            s[tot].r=max(s[u].r,s[tot].r);
        else s[++tot]=s[u];
    }
    for (int u=1;u<=n;u++)
        for (int i=1;i<=tot;i++)
        {
            c[P(s[i].l-a[u])]++;
            c[P(s[i].r-a[u]+1)]--;
        }
    int ans1=0,ans=0,sum=0;
    for (int u=0;u<=2*M;u++)
    {
        sum=sum+c[u];
        if (sum>ans) {ans=sum,ans1=u;}
        else if (sum==ans&&abs(u-M)<abs(ans1-M)) ans1=u;
    }
    printf("%d %d\n",abs(ans1-M),ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值