zoukankan      html  css  js  c++  java
  • CF475F meta-universe

    题意:给你一个无限大矩形中有一些planet,每次可以选择某一没有planet的行或列分割开矩形(分割开以后要求矩形不为空)。问最后能分割成几个矩形?

    标程:

     1 #include<bits/stdc++.h>
     2 #define P pair<int,int>
     3 #define fir first
     4 #define sec second
     5 using namespace std;
     6 const int N=100005;
     7 set<P> X,Y;
     8 int n,x[N],y[N];
     9 int solve(set<P> &a,set<P> &b)//要加&符号,不然set不能覆盖 
    10 {//注意a.rbegin()不能作为指针,只能求值如a.rbegin()->fir 
    11     set<P> ::iterator ta1=a.begin(),ta2=--a.end(),tb1=b.begin(),tb2=--b.end(),nxt,t,ed1,ed2;
    12     while (*ta1<=*ta2||*tb1<=*tb2)
    13     {
    14         assert(!a.empty());
    15         if (ta1!=--a.end())
    16         {
    17          nxt=++ta1;--ta1;
    18          set<P> aa,bb;//定义在内部,如果在定义在外面clear的时候地址会错误
    19          if (ta1->fir+1<nxt->fir){
    20             for (t=a.begin();t!=nxt;)
    21             {
    22                 int u=t->sec;++t;//在没有删除元素之前移动指针,不然会寻不到地址 
    23                 aa.insert(P(x[u],u)),bb.insert(P(y[u],u)),b.erase(P(y[u],u)),a.erase(P(x[u],u));//如果不另储的话,*t移除放在最后 
    24             }
    25             return solve(aa,bb)+solve(a,b);
    26          }
    27         }
    28        if (ta2!=a.begin())
    29        {
    30         nxt=--ta2;++ta2;
    31         set<P> aa,bb;
    32          if (ta2->fir-1>nxt->fir){
    33             for (t=--a.end();t!=nxt;)
    34             {
    35                 int u=t->sec;--t;
    36                aa.insert(P(x[u],u)),bb.insert(P(y[u],u)),b.erase(P(y[u],u)),a.erase(P(x[u],u));
    37            }
    38             return solve(aa,bb)+solve(a,b);
    39          }     
    40         }
    41         if (tb1!=--b.end())
    42         {
    43          nxt=++tb1;--tb1;
    44          set<P> aa,bb;
    45          if (tb1->fir+1<nxt->fir){
    46             for (t=b.begin();t!=nxt;)
    47             {
    48            int u=t->sec;++t;
    49               aa.insert(P(x[u],u)),bb.insert(P(y[u],u)),b.erase(P(y[u],u)),a.erase(P(x[u],u));
    50             }
    51             return solve(aa,bb)+solve(a,b);
    52          }
    53         }
    54        if (tb2!=b.begin())
    55        {
    56          nxt=--tb2;++tb2;
    57          set<P> aa,bb;
    58          if (tb2->fir-1>nxt->fir){
    59             for (t=--b.end();t!=nxt;)
    60             {
    61               int u=t->sec;--t;
    62               aa.insert(P(x[u],u)),bb.insert(P(y[u],u)),b.erase(P(y[u],u)),a.erase(P(x[u],u));
    63             }
    64             return solve(aa,bb)+solve(a,b);
    65          }
    66         }
    67         ed1=--a.end(),ed2=--b.end();
    68         if (ta1==ed1&&tb1==ed2) break;
    69         if (ta1!=ed1) ++ta1,--ta2;
    70         if (tb1!=ed2) ++tb1,--tb2;
    71     }
    72     return 1;
    73 }
    74 int main()
    75 {
    76     scanf("%d",&n);
    77     for (int i=1;i<=n;i++)
    78     {
    79         scanf("%d%d",&x[i],&y[i]);
    80         X.insert(P(x[i],i));Y.insert(P(y[i],i));
    81     }
    82     printf("%d
    ",solve(X,Y));
    83    return 0;
    84 }

    易错点:set操作注意一下。

    题解:set+启发式分割

    将所有的planet存入行set和列set。

    每次从行和列的两边(启发式)往中间找空行/列,然后剖开,递归求解子问题。

    时间复杂度O((n+m)log(n+m))。

  • 相关阅读:
    Rocket
    Rocket
    Rocket
    Rocket
    POJ 1849 树的直径 Two
    SGU 495 Kids and Prizes
    HDU 4336 概率DP 状压
    HDU 4089 && UVa 1498 Activation 带环的概率DP
    SGU 149 树形DP Computer Network
    暑假集训刷题记录
  • 原文地址:https://www.cnblogs.com/Scx117/p/9082795.html
Copyright © 2011-2022 走看看