uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1058

  半平面交求面积最值。直接枚举C(20,8)的所有情况即可。

代码如下:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector> using namespace std; const int N = ;
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
} pt[N], poly[N];
template<class T> T sqr(T x) { return x * x;} typedef Point Vec;
Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);} inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);} struct DLine {
Point p;
Vec v;
double ang;
DLine() {}
DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
bool operator < (const DLine &L) const { return ang < L.ang;}
DLine move(double x) { return DLine(p + normal(v) * x, v);}
} dl[N]; inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > ;}
inline Point dLineIntersect(DLine a, DLine b) { return a.p + a.v * (crossDet(b.v, a.p - b.p) / crossDet(a.v, b.v));} struct Poly {
vector<Point> pt;
Poly() { pt.clear();}
~Poly() {}
Poly(vector<Point> &pt) : pt(pt) {}
Point operator [] (int x) const { return pt[x];}
int size() { return pt.size();}
double area() {
if (pt.size() < ) return 0.0;
double ret = 0.0;
for (int i = , sz = pt.size(); i < sz; i++)
ret += crossDet(pt[i], pt[(i + ) % sz]);
return fabs(ret / 2.0);
}
} ; Point p[N];
DLine q[N];
int halfPlane(DLine *L, int n) {
sort(L, L + n);
int fi, la;
q[fi = la = ] = L[];
for (int i = ; i < n; i++) {
while (fi < la && !onLeft(L[i], p[la - ])) la--;
while (fi < la && !onLeft(L[i], p[fi])) fi++;
q[++la] = L[i];
if (fabs(crossDet(q[la].v, q[la - ].v)) < EPS) {
la--;
if (onLeft(q[la], L[i].p)) q[la] = L[i];
}
if (fi < la) p[la - ] = dLineIntersect(q[la - ], q[la]);
}
while (fi < la && !onLeft(q[fi], p[la - ])) la--;
if (la < fi) return ;
p[la] = dLineIntersect(q[la], q[fi]);
int ret = ;
for (int i = fi; i <= la; i++) poly[ret++] = p[i];
return ret;
} //Poly halfPlane(DLine *L, int n) {
// Poly ret = Poly();
// sort(L, L + n);
// int fi, la;
// Point *p = new Point[n];
// DLine *q = new DLine[n];
// q[fi = la = 0] = L[0];
// for (int i = 1; i < n; i++) {
// while (fi < la && !onLeft(L[i], p[la - 1])) la--;
// while (fi < la && !onLeft(L[i], p[fi])) fi++;
// q[++la] = L[i];
// if (fabs(crossDet(q[la].v, q[la - 1].v)) < EPS) {
// la--;
// if (onLeft(q[la], L[i].p)) q[la] = L[i];
// }
// if (fi < la) p[la - 1] = dLineIntersect(q[la - 1], q[la]);
// }
// while (fi < la && !onLeft(q[fi], p[la - 1])) la--;
// if (la < fi) return ret;
// p[la] = dLineIntersect(q[la], q[fi]);
// for (int i = fi; i <= la; i++) ret.pt.push_back(p[i]);
// return ret;
//} double polyArea(Point *p, int n) {
if (n < ) return 0.0;
double sum = 0.0;
p[n] = p[];
Point O = Point(0.0, 0.0);
for (int i = ; i < n; i++) sum += crossDet(O, p[i], p[i + ]);
return fabs(sum / 2.0);
} double work(int st, int n, double d) {
// cout << st << endl;
for (int i = ; i < n; i++) dl[i] = DLine(pt[i], pt[i + ] - pt[i]).move((st & ( << i)) == ? 0.0 : d);
int tmp = halfPlane(dl, n);
return polyArea(poly, tmp);
// Poly tmp = halfPlane(dl, n);
// return tmp.area();
} int cntBit(int x) {
int cnt = ;
while (x > ) {
if (x & ) cnt++;
x >>= ;
}
return cnt;
} int main() {
// freopen("in", "r", stdin);
int n, k;
double d;
while (~scanf("%d%d%lf", &n, &k, &d) && (n + k + d > EPS)) {
for (int i = ; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
pt[n] = pt[];
double ans = 0.0, area = polyArea(pt, n);
for (int i = , end = << n; i < end; i++) {
if (cntBit(i) <= k) {
// cout << i << endl;
ans = max(ans, area - work(i, n, d));
}
if (sgn(ans - area) == ) break;
}
printf("%.2f\n", ans);
}
return ;
}

能通过POJ的代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector> using namespace std; const int N = ;
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
} pt[N], poly[N];
template<class T> T sqr(T x) { return x * x;} typedef Point Vec;
Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
const double EPS = 1e-;
inline int sgn(double x) { return (x > EPS) - (x < -EPS);} inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);} struct DLine {
Point p;
Vec v;
double ang;
DLine() {}
DLine(Point p, Vec v) : p(p), v(v) { ang = atan2(v.y, v.x);}
bool operator < (const DLine &L) const { return ang < L.ang;}
DLine move(double x) { return DLine(p + normal(v) * x, v);}
} dl[N]; inline bool onLeft(DLine L, Point p) { return crossDet(L.v, p - L.p) > ;}
inline Point dLineIntersect(DLine a, DLine b) { return a.p + a.v * (crossDet(b.v, a.p - b.p) / crossDet(a.v, b.v));} struct Poly {
vector<Point> pt;
Poly() { pt.clear();}
~Poly() {}
Poly(vector<Point> &pt) : pt(pt) {}
Point operator [] (int x) const { return pt[x];}
int size() { return pt.size();}
double area() {
if (pt.size() < ) return 0.0;
double ret = 0.0;
for (int i = , sz = pt.size(); i < sz; i++)
ret += crossDet(pt[i], pt[(i + ) % sz]);
return fabs(ret / 2.0);
}
} ; Point p[N];
DLine q[N], tmpDL[N];
int halfPlane(DLine *L, int n) {
for (int i = ; i < n; i++) tmpDL[i] = L[i];
sort(L, L + n);
int fi, la;
q[fi = la = ] = L[];
for (int i = ; i < n; i++) {
while (fi < la && !onLeft(L[i], p[la - ])) la--;
while (fi < la && !onLeft(L[i], p[fi])) fi++;
q[++la] = L[i];
if (fabs(crossDet(q[la].v, q[la - ].v)) < EPS) {
la--;
if (onLeft(q[la], L[i].p)) q[la] = L[i];
}
if (fi < la) p[la - ] = dLineIntersect(q[la - ], q[la]);
}
for (int i = ; i < n; i++) L[i] = tmpDL[i];
while (fi < la && !onLeft(q[fi], p[la - ])) la--;
if (la < fi) return ;
p[la] = dLineIntersect(q[la], q[fi]);
int ret = ;
for (int i = fi; i <= la; i++) poly[ret++] = p[i];
return ret;
} double polyArea(Point *p, int n) {
if (n < ) return 0.0;
double sum = 0.0;
p[n] = p[];
Point O = Point(0.0, 0.0);
for (int i = ; i < n; i++) sum += crossDet(O, p[i], p[i + ]);
return fabs(sum / 2.0);
} double work(int st, int n, double d) {
// cout << st << endl;
for (int i = ; i < n; i++) dl[i] = DLine(pt[i], pt[i + ] - pt[i]).move((st & ( << i)) == ? 0.0 : d);
int tmp = halfPlane(dl, n);
return polyArea(poly, tmp);
// Poly tmp = halfPlane(dl, n);
// return tmp.area();
} int cntBit(int x) {
int cnt = ;
while (x > ) {
if (x & ) cnt++;
x >>= ;
}
return cnt;
} const double FINF = 1e100;
double ans, d;
void dfs(int id, int tt, int used, int k) {
if (id >= tt) {
int tmp = halfPlane(dl, tt);
ans = min(ans, polyArea(poly, tmp));
return ;
}
dl[id] = DLine(pt[id], pt[id + ] - pt[id]);
dfs(id + , tt, used, k);
if (used >= k) return ;
dl[id] = DLine(pt[id], pt[id + ] - pt[id]).move(d);
dfs(id + , tt, used + , k);
} int main() {
// freopen("in", "r", stdin);
int n, k;
while (~scanf("%d%d%lf", &n, &k, &d) && (n + k + d > EPS)) {
for (int i = ; i < n; i++) scanf("%lf%lf", &pt[i].x, &pt[i].y);
pt[n] = pt[];
double area = polyArea(pt, n);
ans = FINF;
dfs(, n, , k);
printf("%.2f\n", area - ans);
}
return ;
}

——written by Lyon

poj 1271 && uva 10117 Nice Milk (半平面交)的更多相关文章

  1. poj 2451 Uyuw's Concert (半平面交)

    2451 -- Uyuw's Concert 继续半平面交,这还是简单的半平面交求面积,不过输入用cin超时了一次. 代码如下: #include <cstdio> #include &l ...

  2. poj 2451 Uyuw's Concert(半平面交)

    Uyuw's Concert Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8580   Accepted: 3227 De ...

  3. POJ - 1474 :Video Surveillance (半平面交-求核)

    pro:顺时针给定多边形,问是否可以放一个监控,可以监控到所有地方,即问是否存在多边形的核. 此题如果两点在同一边界上(且没有被隔段),也可以相互看到. sol:求多边形是否有核.先给直线按角度排序, ...

  4. POJ 3384 Feng Shui(计算几何の半平面交+最远点对)

    Description Feng shui is the ancient Chinese practice of placement and arrangement of space to achie ...

  5. POJ 3525/UVA 1396 Most Distant Point from the Sea(二分+半平面交)

    Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...

  6. poj 3335(半平面交)

    链接:http://poj.org/problem?id=3335     //大牛们常说的测模板题 ------------------------------------------------- ...

  7. poj 1755 半平面交+不等式

    Triathlon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6461   Accepted: 1643 Descrip ...

  8. poj 1279 半平面交核面积

    Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6668   Accepted: 2725 Descr ...

  9. poj 3335 Rotating Scoreboard(半平面交)

    Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6420   Accepted: 25 ...

随机推荐

  1. 洛谷P1965 转圈游戏 [2013NOIP提高组 D1T1][2017年6月计划 数论04]

    P1965 转圈游戏 题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 ...

  2. 微信小程序之组件开发中的基础知识

    跟着视频开始小程序的项目的开发,视频中这个小程序已经上线了,可以很好的看着小程序的界面进行开发,昨天看了一下具体的需求,觉得真的细节好多啊,而且其中设计的组件的思想也是很好的,能够很好的实现代码的复用 ...

  3. Django项目:CRM(客户关系管理系统)--15--07PerfectCRM实现King_admin显示注册的表01

    <th ><a href="/kingadmin/{% get_app_name admin_class.model %}/{% get_model_name admin_ ...

  4. bzoj 1024 [SCOI2009]生日快乐——模拟

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 可以枚举这边放多少块.那边放多少块. 注意精度.不要每次用x*y/base算有多少块, ...

  5. 批处理启动应用程序(win)

    @echo off net session >nul 2>&1 " ( echo Oops: This tools must run with administrator ...

  6. 微信小程序--轮播图,标题,盒子,tab栏的合成例子

    小程序是什么? 微信小程序,是一种不需要下载安装即可使用的应用,用户扫一扫或搜一下即可打开应用,在微信-发现-小程序可打开应用. 一.小程序的样式编写: 目录结构: app.json { " ...

  7. 提交方式get和post有什么区别

    提交方式post和get有什么区别? (1)post是向服务器传送数据:get是从服务器上获取数据. (2)在客户端,get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个 ...

  8. AC自动机fail树小结

    建议大家学过AC自动机之后再来看这篇小结 fail树就是讲fail指针看做一条边连成的树形结构 fail指针在AC自动机中的含义是指以x为结尾的后缀在其他模式串中所能匹配的最长前缀的长度 所以在模式串 ...

  9. Linux之Shell1

    1.输出命令:echo echo [选项] [输出内容] : -e  支持反斜线控制的字符转换.(类似于C语言的\) \\ 输出\本身 \t Tab键 \n 换行符 \f 换页符 ...  

  10. 一条SQL完成跨数据库实例Join查询

    背景 随着业务复杂程度的提高.数据规模的增长,越来越多的公司选择对其在线业务数据库进行垂直或水平拆分,甚至选择不同的数据库类型以满足其业务需求.原本在同一数据库实例里就能实现的SQL查询,现在需要跨多 ...