codeforces 1028C

codeforces 1028C

codeforces 1028C link

introduction

求一个点,要求这个点最少要被n-1个矩形覆盖

useful knowledge

  • 基数型前后缀 前i个,后i个
  • 序数型前后缀 从开始达第i个,从最后到第i个
  • 很多量都可以用前后缀来管理
    1. 前缀和,后缀和
    2. 前缀最值,后缀最值
    3. 前缀交集,后缀交集

tips

  1. 设置监视哨,简化边界情况的处理
  2. 两个矩形求交集的方法

AC code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<sstream>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
using namespace std;
const int INTMAX=0x7f7f7f7f;
const int INTMIN=-INTMAX;
int n;
struct rect{
    int x1,y1,x2,y2;
    bool valid;
    rect(){valid=true;}
    rect(int a1,int b1,int a2,int b2):
        x1(a1),y1(b1),x2(a2),y2(b2){valid=true;}
    friend istream & operator >>(istream &in,rect &r)
    {
        in>>r.x1>>r.y1>>r.x2>>r.y2;
        return in;
    }
};
rect intersect(const rect &r1,const rect &r2)
{
    rect rt;
    int x1=max(r1.x1,r2.x1),y1=max(r1.y1,r2.y1),
        x2=min(r1.x2,r2.x2),y2=min(r1.y2,r2.y2);
    if(x1>x2||y1>y2||r1.valid==false||r2.valid==false){
            rt.valid=false;
            return rt;
    }
    else return rect(x1,y1,x2,y2);
}
int main()
{
//    freopen("in.txt","r",stdin);
    cin>>n;
    vector<rect>rcts;
    vector<rect>pre,suf;
    rcts.resize(n+10);
    pre.resize(n+10);
    suf.resize(n+10);
    for(int i=0;i<n ;i++ ){
        cin>>rcts[i];
    }
    ///前i个,后i个
    pre[0]=suf[0]=rect(INTMIN,INTMIN,INTMAX,INTMAX);
    for(int i=1;i<=n ;i++ ){
        pre[i]=intersect(pre[i-1],rcts[i-1]);
        suf[i]=intersect(suf[i-1],rcts[n-i]);
    }
    for(int i=0;i<=n ;i++ ){
//        DEBUG(i);
//        DEBUG(pre[i].valid);
//        DEBUG(suf[n-i-1].valid);
        if(pre[i].valid){
            rect t=intersect(pre[i],suf[n-i-1]);
//            DEBUG(t.valid);
            if(t.valid){
                cout<<t.x1<<" "<<t.y1<<endl;
                return 0;
            }
        }
//        cout<<endl;
    }
//    cout<<pre[n].x1<<" "<<pre[n].y1<<endl;
}

原文地址:https://www.cnblogs.com/MalcolmMeng/p/10134646.html