loj6481 #6481. 「ICPC World Finals 2017」Visual Python++
作者:互联网
同时也是CF gym101471L。
题目叙述
给定 \(n\) 个矩形的左上和右下,问是否能够还原出一种方案使得举行只包含或相离,不相交。
题解
考虑每个右下的点匹配离他最近的左上的点。
结论是如果有解,这样匹配就是正确的。
剩下问题是看是否只有嵌套关系,考虑按照 \(x\) 从小到大进行扫描线,每次把矩形的上下边界插入到一颗平衡树中。
容易发现,插入时两个纵坐标相邻,删除时两个纵坐标也相邻,那么就一定都是包含关系。
反思
主要反思一下思考过程。
尝试例子花费40分钟。
想起来以前某个圆相关的扫描线题花费20分钟。
想到这样简单的策略再花费20分钟。
中间不知道该怎么办的楞神还有不知道多少分钟。
正确的做法是先思考10分钟。这10分钟不见得需要尝试例子。
然后至少尝试三个例子。
然后水平展开,看看有哪些可能的方式。并且思维导图式地记录下来。
思考一下以往的套路(有时候要结合尝试),理想情况下5分钟应该能想起来。
另外需要对这个问题进行一些类型的描述。文字上的描述和直觉不一定等价。比如这个题可以描述为扫描线。
注意,尝试例子的时候需要假定一种贪心策略,然后尝试找反例。这样思考更有效率。
猜测贪心策略要根据以往经验,不怕错。
代码
要不还是存一下。
#include <cstdio>
#include <iostream>
#include <set>
#include <algorithm>
#include <vector>
#define fi first
#define se second
#define pii pair<int,int>
#define fail return printf("syntax error\n"),0
using namespace std;
typedef long long LL;
const int MN=1e5+5;
int N;
struct Node{
int x,y,id;
Node():x(0),y(0){}
Node(int _x,int _y):x(_x),y(_y){}
}dot[MN*2];
bool cmp1(const Node &A,const Node &B){return (A.x==B.x)?(A.y<B.y):(A.x<B.x);}
bool cmp2(const Node &A,const Node &B){return A.id<B.id;}
set<pii> s;
int ans[MN];
int lx[MN*2],tx;
vector<pair<pii,bool> > buc[MN*2];
bool cmp(const pair<pii,bool> &x,const pair<pii,bool> &y){
if(x.se==y.se){
if(x.se==0)return (x.fi.se-x.fi.fi)>(y.fi.se-y.fi.fi);
else return (x.fi.se-x.fi.fi)<(y.fi.se-y.fi.fi);
}else return x.se>y.se;
}
int main(){
// freopen("l.in","r",stdin);
// freopen("l.out","w",stdout);
scanf("%d",&N);
for(int i=1;i<=2*N;++i){
scanf("%d%d",&dot[i].x,&dot[i].y),dot[i].id=i;
lx[++tx]=dot[i].x;
}
sort(dot+1,dot+2*N+1,cmp1);
for(int i=1;i<=2*N;++i){
if(dot[i].id<=N){
s.insert(make_pair(dot[i].y,dot[i].id));
}else{
auto it=s.upper_bound(make_pair(dot[i].y,1e9));
if(it==s.begin())fail;
--it;
ans[it->se]=dot[i].id-N;
s.erase(it);
}
}
sort(dot+1,dot+2*N+1,cmp2);
sort(lx+1,lx+tx+1);
tx=unique(lx+1,lx+tx+1)-lx-1;
for(int i=1;i<=2*N;++i)dot[i].x=lower_bound(lx+1,lx+tx+1,dot[i].x)-lx;
for(int i=1;i<=N;++i){
buc[dot[i].x].push_back(make_pair(make_pair(dot[i].y,dot[ans[i]+N].y),1));
buc[dot[ans[i]+N].x].push_back(make_pair(make_pair(dot[i].y,dot[ans[i]+N].y),0));
}
multiset<int> post;
for(int i=1;i<=2*N+1;++i){
sort(buc[i].begin(),buc[i].end(),cmp);
for(auto j:buc[i]){
if(j.se==1){
if(post.count(j.fi.se))fail;
post.insert(j.fi.se);
auto it=post.lower_bound(j.fi.fi);
if(it==post.end()||(*it)!=j.fi.se)fail;
if(j.fi.se!=j.fi.fi&&post.count(j.fi.fi))fail;
post.insert(j.fi.fi);
}else{
auto it=post.lower_bound(j.fi.fi);
post.erase(it);
it=post.lower_bound(j.fi.fi);
if(it==post.end()||(*it)!=j.fi.se)fail;
post.erase(j.fi.se);
}
}
}
for(int i=1;i<=N;++i)printf("%d\n",ans[i]);
// fclose(stdin);
// fclose(stdout);
return 0;
}
标签:const,Python,ICPC,++,int,lx,fi,include,se 来源: https://www.cnblogs.com/YouthRhythms/p/16411507.html