1066

来源:互联网 发布:duet display windows 编辑:程序博客网 时间:2024/06/11 13:12

就是按照Discuss里面所说, interior walls把每个exterior wall分割成许多小段, 这些小段的端点和treasure连一直线, 穿过多少interior再加1(算上凿穿一面外墙)就可以了....

#include <cstdio>#include <cmath>using namespace std;const double EPS = 1e-8;struct point{double x, y;};struct segment{point head, rear;void set(const double xh, const double yh, const double xr, const double yr){head.x = xh;head.y = yh;rear.x = xr;rear.y = yr;}void set(const point &p1, const point &p2){set(p1.x, p1.y, p2.x, p2.y);}};int n;point treasure;segment walls[30], seg[64];int through[64];int index;inline double multi(const double x1, const double y1, const double x2, const double y2){return x1 * y2 - x2 * y1;}inline int cross(const point &p, const segment &seg){const double product = multi(p.x - seg.head.x, p.y - seg.head.y, seg.rear.x - seg.head.x, seg.rear.y - seg.head.y);if(abs(product) < EPS){return 0;}return (product < 0)? -1: 1;}void input(){scanf("%d", &n);for(int i = 0; i < n; ++i){scanf("%lf%lf%lf%lf", &walls[i].head.x, &walls[i].head.y, &walls[i].rear.x, &walls[i].rear.y);}scanf("%lf%lf", &treasure.x, &treasure.y);}inline point &cut(segment& wall, segment &seg){if(seg.head.y == seg.rear.y){if(seg.head.y == wall.head.y){return wall.head;}else{return wall.rear;}}else{if(seg.head.x == wall.head.x){return wall.head;}else{return wall.rear;}}}void solve(){seg[0].set(0.0, 0.0, 100.0, 0.0);seg[1].set(100.0, 0.0, 100.0, 100.0);seg[2].set(100.0, 100.0, 0.0, 100.0);seg[3].set(0.0, 100.0, 0.0, 0.0);through[0] = 1;through[1] = 1;through[2] = 1;through[3] = 1;index = 4;for(int i = 0; i < n; ++i){int snapshot = index;for(int j = 0; j < snapshot; ++j){const int t1 = cross(seg[j].head, walls[i]);const int t2 = cross(seg[j].rear, walls[i]);if(t1 * t2 < 0){point &tmp = cut(walls[i], seg[j]);seg[index].set(seg[j].head, tmp);through[index] = through[j];seg[j].head = tmp;if(cross(seg[j].rear, walls[i]) * cross(treasure, walls[i]) < 0){++through[j];}else{++through[index];}++index;}else if(t1 * t2 > 0){if(cross(treasure, walls[i]) * cross(seg[j].head, walls[i]) < 0){++through[j];}}else{if(0 == t1){if(cross(treasure, walls[i]) * cross(seg[j].rear, walls[i]) < 0){++through[j];}}else{if(cross(treasure, walls[i]) * cross(seg[j].head, walls[i]) < 0){++through[j];}}}}}}void output(){int ans = 0x7FFFFFFF;for(int i = 0; i < index; ++i){if(through[i] < ans){ans = through[i];}}printf("Number of doors = %d\n", ans);}int main(){input();solve();output();return 0;}

原创粉丝点击