【题意】在二维平面上以(0,0)为左下角,(w,d)为右上角的矩形区域内有一些点,每个点代表一个人,每个人将会面对一个方向(东南西北),一个人的视野范围是以该点为顶点的直角,角平分线与其所面对的方向平行,角的两条边会与矩形交于两点,矩形上两点之间的部分,为该人的可视部分。为了让每个人都能知道时间,你需要在矩形的边界上放置一些时钟(视为一个点),使得每个人的可以部分内都至少有一个时钟,求最少需要放置几个时钟。
【思路】记录下每个点在边界上的交点,记录区间,然后沿逆时针方向将边界拉成直线(由于是环要*2),寻找最大不相交的区间个数(没有公共点)
【代码】
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define maxn 2003
#define inf 100000007
using 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;
}