POJ 1899 Farmer Bill's Problem

来源:互联网 发布:网络教育学费多少 编辑:程序博客网 时间:2024/05/24 05:30

题意:

给一个矩形和在矩形内的N个圆,用若干个没有任何公共部分(甚至公共点)的矩形(边平行于大矩形的边)包含住这N个圆。要是这些用于包裹的矩形的面积最小,求剩下的面积。

思路:

找到有公共部分的矩形就合并,直到不能合并为止。错了好多遍。。。不知道为什么。。。

code:

#include <cstdio>#include <algorithm>using namespace std;#define N 105int x, y, n, tx, ty, r, ans;struct Rec{int sx, sy, ex, ey;bool vis;Rec() {}Rec(int _sx, int _sy, int _ex, int _ey, bool f): sx(_sx), sy(_sy), ex(_ex), ey(_ey), vis(f) {}bool contains(int x, int y){return (x<=ex && x>=sx && y<=ey && y>=sy);}bool inter(Rec &r){if (contains(r.sx, r.sy)) return true;if (contains(r.sx, r.ey)) return true;if (contains(r.ex, r.sy)) return true;if (contains(r.ex, r.ey)) return true;if (r.contains(sx, sy)) return true;if (r.contains(sx, ey)) return true;if (r.contains(ex, sy)) return true;if (r.contains(ex, ey)) return true;return false;}void merge(Rec &r){sx = min(sx, r.sx);sy = min(sy, r.sy);ex = max(ex, r.ex);ey = max(ey, r.ey);}int area(){return (ey-sy) * (ex-sx);}void print(){printf("%d %d %d %d %d\n", sx, sy, ex, ey, vis);}};Rec rec[N];int main(){scanf("%d%d%d", &x, &y, &n);ans = x*y;for (int i = 0; i < n; ++ i){scanf("%d%d%d", &tx, &ty, &r);rec[i] = Rec(tx-r, ty-r, tx+r, ty+r, false);}bool flag;while (true){flag = false;for (int i = 0; i < n; ++ i) if (!rec[i].vis){for (int j = 0; j < n; ++ j) if (j!=i && !rec[j].vis && rec[i].inter(rec[j])){flag = true;rec[j].vis = true;rec[i].merge(rec[j]);}}if (!flag) break;}for (int i = 0; i < n; ++ i) if (!rec[i].vis)ans -= rec[i].area();printf("%d\n", ans);}


原创粉丝点击