uva 609 - Metal Cutting(暴力)

来源:互联网 发布:营销网络地图制作 编辑:程序博客网 时间:2024/05/18 15:57

题目连接:uva 609 - Metal Cutting


题目大意:给出一个矩形,以及n个点,将切出以n个点为顶点的n边形,且最短的切割距离。点按照顺时针给出,不会有三个点在同一条直线上。


解题思路:要切的直线以及确定了,这要枚举切的顺序即可,用next_permutation枚举枚举所有切割顺序;对于每中切割顺序,将所有已经切过的边,以及边界保留,在切下一个边是,判断是否与前面的切边有交点,将所有交点保留,然后枚举切边线段外两点的最短距离。


#include <stdio.h>#include <string.h>#include <math.h>#include <vector>#include <algorithm>using namespace std;const int N = 10;const double INF = 0x3f3f3f3f3f3f3f3f;const double eps = 1e-9;struct Point {double x, y;Point () { };Point (double x, double y) {this->x = x; this->y = y;}}p[N];struct Line {int id;double A, B, C;Point p1, p2;void set(Point a, Point b) {p1 = a; p2 = b;A = p2.y - p1.y;B = p1.x - p2.x;C = -(B * p1.y + A * p1.x);}}line[N];int n;double r, l;vector<Line> g;bool cmp(Line a, Line b) {return a.id < b.id;}double distant (double x, double y) {return sqrt(x * x + y * y);}void init () {scanf("%lf%lf%d", &r, &l, &n);for (int i = 0; i < n; i++)scanf("%lf%lf", &p[i].x, &p[i].y);for (int i = 0; i < n; i++) {line[i].set(p[i], p[(i+1)%n]);line[i].id = i;}}inline bool judge (Point a, Point b, Point c, Point d) {int xup, xdown, yup, ydown;xup = xdown = yup = ydown = 0;double Max = max(c.x, d.x), Min = min(c.x, d.x);if (a.x - Max > -eps || b.x - Max > -eps) xup = 1;if (a.x - Min < eps || b.x - Min < eps) xdown = 1;Max = max(c.y, d.y); Min = min(c.y, d.y);if (a.y - Max > -eps || b.y - Max > -eps) yup = 1;if (a.y - Min < eps || b.y - Min < eps) ydown = 1;return xup + xdown + yup + ydown == 4;}inline Point find (Line a, Line b) {double x = (a.B * b.C - b.B * a.C) / (a.A * b.B - a.B * b.A);double y = (a.A * b.C - b.A * a.C) / (b.A * a.B - a.A * b.B);return Point(x, y);}inline double cat (int u) {Point v[20];int cnt = 0;for (int i = 0; i < g.size(); i++) {double Ai = g[i].A * line[u].B;double Bi = g[i].B * line[u].A;if (fabs(Ai - Bi) < eps) continue;Point k = find(g[i], line[u]);v[cnt++] = k;}double ans = INF;for (int i = 0; i < cnt; i++) {for (int j = i+1; j < cnt; j++) if (judge(v[i], v[j], line[u].p1, line[u].p2)) {double dis = distant(v[i].x - v[j].x, v[i].y - v[j].y);ans = min(ans, dis);}}return ans;}double del () {g.clear();Line t;t.set(Point(0, 0), Point(r, 0));g.push_back(t);t.set(Point(0, 0), Point(0, l));g.push_back(t);t.set(Point(r, l), Point(r, 0));g.push_back(t);t.set(Point(r, l), Point(0, l));g.push_back(t);double len = 0;for (int i = 0; i < n; i++) {len += cat(i);g.push_back(line[i]);}return len;}double solve () {double ans = INF;sort(line, line + n, cmp);do {ans = min(ans, del());} while (next_permutation(line, line + n, cmp));return ans;}int main () {int cas;scanf("%d", &cas);while (cas--) {init ();printf("Minimum total length = %.3lf\n", solve () );if (cas) printf("\n");}return 0;}



1 0
原创粉丝点击