[AIZU1359] Wall Clocks [2015 ACM-ICPC Asia Tsukuba Regional Contest D]

来源:互联网 发布:李小龙身体实际数据 编辑:程序博客网 时间:2024/05/02 02:17

题意

一些人在一个矩形的房间里,每个人有一个坐标,和一个方向,视角的宽度是90度,于是每个人都会看到墙壁的一部分。现在要求在墙壁上挂最少的时钟使得每个人至少可以看到一个时钟。

题解

以每个人左侧视线(或右侧)与墙的交点为关键字排序,再枚举从每个人开始将墙壁断开,形成一条直线,直线上有一些线段,要求放置一些点,使得每条线段至少包含一个点。
此时可以进行贪心,以线段左端点位置为第一关键字,右端点为第二关键字,从左向右进行压栈,直到必须放置第二个点时弹栈。

代码

比赛时没打模板
具体操作时要找到从一个点出发,射向某个方向的射线和矩形边框的交点,射线方向分四种,每一种有两种相交情况。

#include <bits/stdc++.h>using namespace std;#define  maxn  1010LL#define  up(x)    (x)#define  right(x) (w+d-(x))#define  down(x)  (w+d+w-(x))#define  left(x)  ((w+d+w+(x))%(w+d+w+d))struct seg {    int l,r;    bool operator < (const seg&b) const {        if (l == b.l) return r < b.r ;        return l < b.l;    }} s[maxn] ;int d , w , x , y , n;int leftup(int x,int y) {    if (x > d-y) return up(x-d+y);    else return left(x+y);}int rightup(int x,int y) {    if (w-x > d-y) return up(x+d-y) ;    else return right(y+w-x) ;}int leftdown(int x,int y) {    if (x > y) return down(x-y) ;    else return left(y-x) ;}int rightdown(int x,int y) {    if (w-x > y) return down(x+y);    else return right(y-w+x) ;}int sta[maxn],top;int main() {int dir,ANS,ans,nowright;    scanf("%d%d%d", &n, &w, &d);    for (int i = 1 ; i <= n ; i ++ ) {        scanf("%d%d", &x, &y);        while (dir=getchar(),dir==' ');        if (dir == 'N') {            s[i].l = leftup(x,y) ;            s[i].r = rightup(x,y) ;        }        if (dir == 'E') {            s[i].l = rightup(x,y) ;            s[i].r = rightdown(x,y) ;        }        if (dir == 'S') {            s[i].l = rightdown(x,y) ;            s[i].r = leftdown(x,y) ;        }        if (dir == 'W') {            s[i].l = leftdown(x,y) ;            s[i].r = leftup(x,y) ;        }        if (s[i].r < s[i].l) s[i].r += w+w+d+d ;  //  printf("i = %d, l = %d , r = %d\n",i,s[i].l,s[i].r);    }    sort(s+1,s+n+1);    ANS = n ;    for (int i = 1 , j , len ; i <= n ; i ++ ) {        ans = 0;        sta[top=1] = i ;        nowright = s[i].r;        len = 1 ;        j = i ;        while (++len <= n) {            j = j % n + 1 ;            if (s[j].l > nowright) {                ans ++ ;                top = 0 ;                sta[++top] = j ;                nowright = s[j].r ;            } else {                sta[++top] = j ;                if (s[j].r < nowright) nowright = s[j].r ;            }        }        ans ++ ;        if (ans < ANS) ANS = ans ;        s[i].l += w+w+d+d ;        s[i].r += w+w+d+d ;    }    printf("%d\n", ANS) ;    return 0;}
0 0
原创粉丝点击