New Year and Conference
Codeforces 1284D
水平有限,如有疏漏,墙裂欢迎提出
思路,代码借鉴题解
Codeforces原题
简要题意:给定若干组区间,每一组区间由
口胡谁都会,我要看代码
#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
const int MAX=100005;
struct node{
int starta,enda,startb,endb;
}h[MAX];
struct point{
int t,startb,endb;
bool in;
bool operator < (const point &a)const{
if(a.t!=t)return a.t>t;
else return a.in>in; //这里要注意处在同一时间点的情况,要先删除过期的
}
}t[MAX<<1];
int n,cnt;
multiset<int> start,endd;
multiset<int>::iterator it;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d %d %d %d",&h[i].starta,&h[i].enda,&h[i].startb,&h[i].endb);
//整体思路,先固定a剧场时间是交的,如果b剧场没交(与a剧场能交的 那些演讲的b剧场时间),那么就输出NO
for(int i=1;i<=n;i++){
t[++cnt]=point{h[i].starta,h[i].startb,h[i].endb,1};
t[++cnt]=point{h[i].enda+1,h[i].startb,h[i].endb,0}; //在enda+1处要先将已经过期的删除,不要影响新开始的
}
sort(t+1,t+cnt+1);
for(int i=1;i<=cnt;i++){
if(t[i].in){
if(!start.empty()){ //存在没有结束的演讲,也就是在a剧场它们交了
it=start.end(),it--;
if(t[i].endb<*it){ //存在在b剧场无法交的演讲,那么就NO
printf("NO");
return 0;
}
it=endd.begin();
if(*it<t[i].startb){ //存在在b剧场无法交的演讲,那么就NO
printf("NO");
return 0;
}
}
start.insert(t[i].startb),endd.insert(t[i].endb);
}else{
start.erase(start.find(t[i].startb));
endd.erase(endd.find(t[i].endb));
}
}
//再反之固定b剧场相交,操作相同
cnt=0,start.clear(),endd.clear();
for(int i=1;i<=n;i++){
t[++cnt]=point{h[i].startb,h[i].starta,h[i].enda,1};
t[++cnt]=point{h[i].endb+1,h[i].starta,h[i].enda,0};
}
sort(t+1,t+cnt+1);
for(int i=1;i<=cnt;i++){
if(t[i].in){
if(!start.empty()){ //存在没有结束的演讲,也就是在b剧场它们交了
it=start.end(),it--;
if(t[i].endb<*it){ //存在在a剧场无法交的演讲,那么就NO
printf("NO");
return 0;
}
it=endd.begin();
if(*it<t[i].startb){ //存在在a剧场无法交的演讲,那么就NO
printf("NO");
return 0;
}
}
start.insert(t[i].startb),endd.insert(t[i].endb);
}else{
start.erase(start.find(t[i].startb));
endd.erase(endd.find(t[i].endb));
}
}
printf("YES");
return 0;
}