POJ 2540 ZOJ 1886 Hotter Colder 半平面交

来源:互联网 发布:java工程师面试技巧 编辑:程序博客网 时间:2024/05/21 19:38

之前研究性学习写了这道题。。然而写论文的时候并没有做233,然后现在AC后发现论文里的好像就写错了。。

以下是以前写的粗略的题解。

孩子们的游戏Hotter Colder的游戏规则:AB在房间内藏了什么东西的时候离开房间,到(0,0)并且访问房间内其他位置。当A到了一个新未知,如果新位置相对于原来的位置更近,则B会说"Hotter",更远"Colder",不变"Same"。你将获得B每次说"Hotter","Colder""Same"的信息,同时包含A的位置。求每次信息更新后房间的可能有效区域。如果信息矛盾,面积为0。例如:(0,0)->(10,10): Colder, 面积50; ->(10,0): Hotter, 面积37.5; ->(0,0): Colder, 面积12.5; ->(10,10) Hotter, 面积0.

显然,对于一次坐标移动,比如(0,0)->(10,10)靠的更远,可以理解为要找的东西的坐标(x,y)满足:。即直线是直线l(过点(0,0)(10,10))的中垂线。对于每次坐标移动我们都建立一个约束,那么可行域面积就是我们要求的。当然如果约束矛盾可行域面积就为0。我们利用半平面交解决该问题。

对于一次移动,其向量的法向量为逆时针旋转90°后的向量,此时的面积就是这些法向量左手半平面交的面积,然后套模板。

SAME的话因为点在中垂线上,所以面积就为0了。我就随便加了个向量把结果卡成0了。。挺懒的233。

话说O(n^2)的算法对于这道题好像很优越啊,可惜不会233。

之前竟然贴成错误的代码了。。

#include <cstdio>#include <cmath>#include <vector>#include <algorithm>using namespace std;const int N = 3333;struct Point {    double x, y;    Point(){}    Point(double _x, double _y) : x(_x), y(_y) {}    Point operator +(const Point &b) const { return Point(x + b.x, y + b.y); }    Point operator -(const Point &b) const { return Point(x - b.x, y - b.y); }    double operator *(const Point &b) const { return x * b.y - y * b.x; }    Point operator *(double b) const { return Point(b * x, b * y); }    Point normal() { return Point(-y, x); }} p[N], poly[N];struct Line {    Point x, v;    double ang;    Line(){}    Line(const Point &_x, const Point &_v) : x(_x), v(_v), ang(atan2(_v.y, _v.x)) { }        bool operator <(const Line &b) const {        if (ang == b.ang) return v * (b.x - x) < 0; // 极角相等时,这么算的叉积表示a在b的左边时返回Line a < b,unique的时候就会选择a而丢掉b。        return ang < b.ang;    }        bool operator ==(const Line &b) const { return ang == b.ang; }        Point intersection(const Line &b) {        Point u = x - b.x;        double t = (b.v * u) / (v * b.v); // 画了图才知道这么写的意思。。        return x + v * t;    }};vector<Line> lines;bool right(const Point &p, const Line &l) {    return l.v * (p - l.x) <= 0;}int half_plane_intersection(vector<Line> l, Point poly[]) {    static Line q[N];    sort(l.begin(), l.end());    vector<Line>::iterator end = unique(l.begin(), l.end())++, it = l.begin();    int f = 1, r = 0, m = 0;    q[++r] = *it++; q[++r] = *it++;    while (it != end) {        while (f < r && right(q[r].intersection(q[r - 1]), *it)) r--;        while (f < r && right(q[f].intersection(q[f + 1]), *it)) f++;        q[++r] = *it++;    }    while (f < r && right(q[r].intersection(q[r - 1]), q[f])) r--; // 还要处理首尾    while (f < r && right(q[f].intersection(q[f + 1]), q[r])) f++;    q[r + 1] = q[f];    for (int i = f; i <= r; i++)        poly[++m] = q[i].intersection(q[i + 1]);    return m;}double calc_area(Point poly[], int m) {    double ans = 0;    if (m <= 2) return ans;    poly[m + 1] = poly[1];    for (int i = 1; i <= m; i++)        ans += poly[i] * poly[i + 1];    return fabs(ans) / 2;}int main() {    char op[10];    p[0] = Point(0, 0);    lines.push_back(Line(Point(0, 0), Point(0, -1)));    lines.push_back(Line(Point(0, 0), Point(1, 0)));    lines.push_back(Line(Point(10, 10), Point(0, 1)));    lines.push_back(Line(Point(10, 10), Point(-1, 0)));    for(int j = 1; scanf("%lf%lf%s", &p[j].x, &p[j].y, op) != EOF; j++) {        if (op[0] == 'S') lines.push_back(Line(Point(0, 0), Point(0, 1)));        lines.push_back(Line((p[j] + p[j - 1]) * 0.5, (p[j] - p[j - 1]).normal() * (op[0] == 'H' ? -1 : 1)));        int m = half_plane_intersection(lines, poly);        printf("%.2lf\n", calc_area(poly, m));    }    return 0;}



Hotter Colder
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3004 Accepted: 1213

Description

The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player A re-enters at position (0,0) and then visits various other positions about the room. When player A visits a new position, player B announces "Hotter" if this position is closer to the object than the previous position; player B announces "Colder" if it is farther and "Same" if it is the same distance.

Input

Input consists of up to 50 lines, each containing an x,y coordinate pair followed by "Hotter", "Colder", or "Same". Each pair represents a position within the room, which may be assumed to be a square with opposite corners at (0,0) and (10,10).

Output

For each line of input print a line giving the total area of the region in which the object may have been placed, to 2 decimal places. If there is no such region, output 0.00.

Sample Input

10.0 10.0 Colder10.0 0.0 Hotter0.0 0.0 Colder10.0 10.0 Hotter

Sample Output

50.0037.5012.500.00


0 0
原创粉丝点击