ssoj2868(最大不相交区间)

来源:互联网 发布:uml画图软件 编辑:程序博客网 时间:2024/05/21 17:28

【题意】在二维平面上以(0,0)为左下角,(w,d)为右上角的矩形区域内有一些点,每个点代表一个人,每个人将会面对一个方向(东南西北),一个人的视野范围是以该点为顶点的直角,角平分线与其所面对的方向平行,角的两条边会与矩形交于两点,矩形上两点之间的部分,为该人的可视部分。为了让每个人都能知道时间,你需要在矩形的边界上放置一些时钟(视为一个点),使得每个人的可以部分内都至少有一个时钟,求最少需要放置几个时钟。

【思路】记录下每个点在边界上的交点,记录区间,然后沿逆时针方向将边界拉成直线(由于是环要*2),寻找最大不相交的区间个数(没有公共点)

【代码】

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define maxn 2003#define inf 100000007using namespace std;pair<int,int > p[maxn];int n,w,d,len,s[maxn],t[maxn];int get(){    char c;while(!isdigit(c=getchar()));    int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;    return v;}void init(){    n=get();w=get();d=get();    len=(w+d)<<1;    int x,y;char ch;int x1,y1,x2,y2;    for(int i=1;i<=n;++i){    x=get();y=get();ch=getchar();while(ch!='E' && ch!='W' && ch!='S' && ch!='N')ch=getchar();    if(ch=='E'){x1=x+y;if(x1>w)y1=x1-w,x1=w;else y1=0;x2=x+d-y;if(x2>w)y2=d-x2+w,x2=w;else y2=d;}else if(ch=='W'){    x1=x-d+y;    if(x1<0)y1=d+x1,x1=0;else y1=d;x2=x-y;    if(x2<0)y2=-x2,x2=0;else y2=0;}else if(ch=='S'){    x1=x-y;    if(x1<0)y1=-x1,x1=0;    else y1=0;    x2=x+y;    if(x2>w)y2=x2-w,x2=w;    else y2=0;}else if(ch=='N'){    x1=x+d-y;    if(x1>w)y1=d-x1+w,x1=w;    else y1=d;    x2=x-d+y;    if(x2<0)y2=d+x2,x2=0;    else y2=d;}if(x1==0 || y1==d)s[i]=len-x1-y1;else s[i]=x1+y1;if(x2==0 || y2==d)t[i]=len-x2-y2;else t[i]=x2+y2;if(t[i]<s[i])t[i]+=len;s[i+n]=s[i]+len;t[i+n]=t[i]+len;p[i]=make_pair(t[i],s[i]);p[i+n]=make_pair(t[i+n],s[i+n]);}sort(p+1,p+1+n+n);}void solveit(){int ans=0;    for(int i=1;i<=n;++i){    int tmp=0,lst=0;    for(int j=i;p[j].first<p[i].second+len;++j){    if(lst<p[j].second){    ++tmp;lst=p[j].first;}}    ans=max(ans,tmp);}printf("%d\n",ans);}int main(){    init();    solveit();    return 0;}


0 0
原创粉丝点击