zoukankan      html  css  js  c++  java
  • BZOJ4925(裸裸的差分)

    这种大水题,我还是没有想出来,明明都知道了是差分了。。。。

    好了我们来看看,先将有重叠的区间(房子)合并(反正效果都一样),这样我们就得到了多段不重叠的区间。

    然后我们枚举每一个点和每一条线段,比如说我们枚举了p这个点它在x,还有两段分别在x1,y1的一条线段,很明显我们最终如果移动的位置在x1-x~y1-x之间的话这个点是会为答案做贡献的,所以我们相当于给一个数组的x1-x~y1-x这一段加上一,最后看看哪个位置值最大,因为之前的区间已经是不重叠了,所以不必担心一个点会被多次计数。

    复杂度O(nm),可以过了。

    下面是程序

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #define maxm 1009
    #define maxn 10009
    #define maxx 1000009
    using namespace std;
    struct ding{
      int l,r;
    }a[maxm],c[maxm];
    int cnt,b[maxn],n,m,p,ans[maxx+maxx+100],now2,now;
    bool cmp(ding x,ding y)
    {
      return x.l==y.l?x.r<y.r:x.l<y.l;
    }
    int main()
    {
      //freopen("plan6.in","r",stdin);
      //freopen("plan.out","w",stdout);
      scanf("%d%d",&n,&m);
      cnt=0;
      for (int i=1;i<=n;i++) scanf("%d",&b[i]);
      for (int i=1;i<=m;i++) scanf("%d%d",&a[i].l,&a[i].r);
      sort(a+1,a+1+m,cmp);
      ding tot=a[1];
      for(int i=2;i<=m;i++)
       if (a[i].l<=tot.r) tot.r=max(tot.r,a[i].r);
       else c[++cnt]=tot,tot=a[i];
      c[++cnt]=tot;
      for (int i=0;i<=maxx+maxx;i++) ans[i]=0;
      for (int i=1;i<=n;i++)
      for (int j=1;j<=cnt;j++)
      {
          ans[c[j].l-b[i]+maxx]++;
          ans[c[j].r-b[i]+1+maxx]--;
        //cout<<ans[c[j].l-b[i]+maxx]<<" "<<ans[c[j].r-b[i]+1+maxx]<<endl;
      }
      now2=maxx;p=0;
      for (int i=1;i<=maxx+maxx;i++)
      {
       p+=ans[i];
       if (p>now)
       {
        now2=abs(i-maxx);
        now=p;
       }
       if (p==now) now2=min(abs(i-maxx),now2);
      }
      printf("%d %d",now2,now);
      return 0;
    }
  • 相关阅读:
    农夫安全第二季课程-3.vmware ESXIv2
    六、表达式:前缀&&后缀
    五、数据类型(1):整数&&带小数点的数
    四、变量和常量
    三、简单的输入输出
    二、第一个C程序:Hello World!
    一、环境的安装Dev-C++
    .Net基础之5——复杂数据类型
    .Net基础之4——流程控制
    .Net基础之3——运算符
  • 原文地址:https://www.cnblogs.com/2014nhc/p/7799824.html
Copyright © 2011-2022 走看看