codeforces 1028 C. Rectangles (前缀后缀,矩形相交)

版权声明:本文为博主原创文章,转载请注明出处~~ https://blog.csdn.net/hxc2101/article/details/82558511

题目:http://codeforces.com/contest/1028/problem/C

题意:有n个矩形,给出左下角和右上角的坐标,已知存在n-1个矩形同时有公共区域(边、顶点也算),要求输出一个点,要求它同时在n-1个矩形中

思路:一开始想的是 比较像 线段求重合区间的题,想纵坐标横坐标离散化后,都用线段树维护,比较麻烦

简单来讲,就是从前往后 和 从后往前 共扫两遍 即可

其实,每加进去一个矩形重合区域左下角的坐标(x1,y1)是一直在往右或往上跑,同样右上角的坐标(x2,y2)一直在往左或往下跑。那么,只需要 pre[i].x1=max(pre[i-1].x1,rec[i].x1); pre[i].x2=min(pre[i-1].x2,rec[i].x2); 纵坐标同理。(这表示的是假设前 i 个矩形全部有公共区域,求得的公共区域的左下角和右上角的坐标) 然后再从后往前也扫一遍即可。

因为题目要求的是 n-1个矩形,又前缀后缀都求出来了,那么只需要暴力扫一遍,枚举去掉某一个矩形,即将他前面(前缀)所有矩形的公共区域的两个坐标 与 他后面(后缀)所有矩形的公共区域的两个坐标 分别取一下max,min,就是剩下的n-1块矩形的公共区域的两个坐标了,再看看 这两个坐标是否合法即可 (可以发现,若两个矩形是不相交的,那么照上一段里面 那样直接取max,min算出来的(x1,y1)(x2,y2),已经两者的大小关系已经不符合左下角和右上角的关系了)

#include <bits/stdc++.h>
//#pragma GCC optimize(3)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mkp(a,b) make_pair(a,b)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define fi first
#define se second
#define lc (d<<1) //d*2
#define rc (d<<1|1) //d*2+1
#define eps 1e-9
#define dbg(x) cerr << #x << " = " << x << "\n";
#define mst(a,val) memset(a,val,sizeof(a))
#define stn(a) setprecision(a)//小数总有效位数
#define stfl setiosflags(ios::fixed)//点后位数:cout<<stfl<<stn(a);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double PI=3.1415926535897932;
const int MAXN=1e5+10;
const ll mod=1e9+7;
ll inline mpow(ll a,ll b){ll ans=1;a%=mod;while(b){if(b&1)ans=(ans*a)%mod;a=(a*a)%mod,b>>=1;}return ans;}
int inline sgn(double x){return (x>-eps)-(x<eps);} //a<b:sgn(a-b)<0
priority_queue<int,vector<int>,greater<int> > qu; //up
priority_queue<int,vector<int>,less<int> > qd; //dn
const int inf = 0x3f3f3f3f; //9
const ll inff = 0x3f3f3f3f3f3f3f3f; //18

int n;
struct Rec
{
    int x1=-inf,y1=-inf,x2=inf,y2=inf;
}rec[150000],pre[150000],suf[150000];

int main()
{
    fio;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>rec[i].x1>>rec[i].y1>>rec[i].x2>>rec[i].y2;
    for(int i=1;i<=n;i++)
    {
        pre[i].x1=max(pre[i-1].x1,rec[i].x1);
        pre[i].y1=max(pre[i-1].y1,rec[i].y1);
        pre[i].x2=min(pre[i-1].x2,rec[i].x2);
        pre[i].y2=min(pre[i-1].y2,rec[i].y2);
    }
    for(int i=n;i>=1;i--)
    {
        suf[i].x1=max(suf[i+1].x1,rec[i].x1);
        suf[i].y1=max(suf[i+1].y1,rec[i].y1);
        suf[i].x2=min(suf[i+1].x2,rec[i].x2);
        suf[i].y2=min(suf[i+1].y2,rec[i].y2);
    }
    int tmpx1=-inf,tmpy1=-inf,tmpx2=inf,tmpy2=inf;
    for(int i=1;i<=n;i++)
    {
        tmpx1=-inf,tmpy1=-inf,tmpx2=inf,tmpy2=inf;
        tmpx1=max(pre[i-1].x1,suf[i+1].x1);
        tmpy1=max(pre[i-1].y1,suf[i+1].y1);
        tmpx2=min(pre[i-1].x2,suf[i+1].x2);
        tmpy2=min(pre[i-1].y2,suf[i+1].y2);
        if(tmpx1<=tmpx2&&tmpy1<=tmpy2) {cout<<tmpx1<<" "<<tmpy1<<endl;return 0;}
    }
}

猜你喜欢

转载自blog.csdn.net/hxc2101/article/details/82558511