题目链接:http://poj.org/problem?id=1271
Time Limit: 1000MS Memory Limit: 10000K

Description

Little Tomy likes to cover his bread with some milk. He does this by putting it in the cup so that one of its sides (called bottom side) touches the bottom of the cup, just as the picture below:

Since the milk in the cup is limited, only part of the bread is covered with milk(as shown in the pictures). That is, only the area between the surface of the milk and the bottom side of the bread is covered. Note that the distance between these two lines is always h - the depth of the milk, which is also known to him.

Tomy wants to cover this bread with largest possible area of milk in this way, but he doesn't want to do more than k actions. Help him, will you?

(You may assume that the cup is wide enough, wider than any side of the bread, so it's possible to cover any side completely)

Input

The input will contain no more than 10 test cases. Each test case begins with a line containing three integers n,k and h (3<=n<=20, 0<=k<=8, 0<=h<=10). A piece of bread is guaranteed to be a convex polygon of n vertices. In the following n lines, each line contains two integers xi and yi(0<=xi,yi<=1000), representing the Cartesianism coordinate of the ith vertex. The vertices are anti-clockwise numbered. The test case containing n=0, k=0, h=0 will terminate the input, you should not give an answer to this case.

Output

Output the area of the largest possible area of bread covered with milk with two decimal places. Output one line for each test case.

Sample Input

4 2 1
1 0
3 0
5 2
0 4
0 0 0

Sample Output

7.46

Problem solving report:

Description: 给一个凸多边形的面包,和一瓶深度为h的牛奶,要沾牛奶k次,求可以沾到牛奶的面包的面积。
Problem solving: 半平面相交.保存各个边被牛奶沾后的位置,即将直线向内推进h,用DFS找出要沾的边,对于每一种情况进行一次半平面交,然后计算剩下的面积,每次选取最小的面积,最后用总面积减去得到的面积就是答案了。

Accepted Code:

//#include <bits/stdc++.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 25;
const double eps = 10-8;
const double inf = 0x3f3f3f3f3f;
int n, k, vis[MAXN];
double min_;
typedef struct point {double x, y;
}vect;
struct line {vect p;point u, v;
}Sl[MAXN], Sl_[MAXN];
vect operator - (const point a, const point b) {vect p;p.x = a.x - b.x;p.y = a.y - b.y;return p;
}
int pnz(double x) {return x < -eps ? -1 : x > eps ? 1 : 0;
}
double Cross(const vect a, const vect b) {return a.x * b.y - a.y * b.x;
}
double dist(const point a, const point b) {return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool Onleft(const point p, const line l) {return pnz(Cross(l.p, p - l.u)) > 0;
}
point Inter(const line a, const line b) {point p;double t = Cross(b.p, a.u - b.u) / Cross(a.p, b.p);p.x = a.u.x + t * a.p.x;p.y = a.u.y + t * a.p.y;return p;
}
void Mobile(line l[], int n, double r) {double dis, dx, dy;for (int i = 0; i < n; i++) {dis = dist(l[i].u, l[i].v);dx = (l[i].v.y - l[i].u.y) / dis * r;dy = (l[i].v.x - l[i].u.x) / dis * r;l[i].u.x -= dx, l[i].u.y += dy;l[i].v.x -= dx, l[i].v.y += dy;}
}
double Area(const point p[], int n) {double area = 0;for (int i = 1; i < n - 1; i++)area += Cross(p[i] - p[0], p[i + 1] - p[0]);return area / 2;
}
double Halfplane(line Sline[], int n) {point Spt[MAXN];int Q[MAXN] = {0};int l = 0, r = 0;for (int i = 1; i < n; i++) {while (l < r && !Onleft(Spt[r - 1], Sline[i]))r--;while (l < r && !Onleft(Spt[l], Sline[i]))l++;Q[++r] = i;if (!pnz(Cross(Sline[i].p, Sline[Q[r - 1]].p))) {r--;if (Onleft(Sline[i].u, Sline[Q[r]]))Q[r] = i;}else Spt[r - 1] = Inter(Sline[i], Sline[Q[r - 1]]);}while (l < r && !Onleft(Spt[r - 1], Sline[Q[l]]))r--;while (l < r && !Onleft(Spt[l], Sline[Q[r]]))l++;if (r - l < 2)return 0;Spt[r] = Inter(Sline[Q[l]], Sline[Q[r]]);return Area(Spt + l, r - l + 1);
}
double slove() {int cnt = 0;line Sline[MAXN];for (int i = 0; i < n; i++)if (vis[i])Sline[cnt++] = Sl_[i];else Sline[cnt++] = Sl[i];return Halfplane(Sline, cnt);
}
void DFS(int l, int s) {if (l >= k) {min_ = min(min_, slove());return ;}if (s >= n)return ;for (int i = 0; i < 2; i++) {vis[s] = i;DFS(l + i, s + 1);}vis[s] = 0;
}
void Copy(line l_[], line l[], int n) {for (int i = 0; i < n; i++)l_[i] = l[i];
}
int main() {double r;point p[MAXN];while (scanf("%d%d%lf", &n, &k, &r), n + k + r) {min_ = inf;for (int i = 0; i < n; i++)scanf("%lf%lf", &p[i].x, &p[i].y);if (!k || !r) {printf("0.00\n");continue;}p[n] = p[0];for (int i = 0; i < n; i++) {Sl[i].u = p[i];Sl[i].v = p[i + 1];Sl[i].p = p[i + 1] - p[i];}Copy(Sl_, Sl, n);Mobile(Sl_, n, r);k = min(k, n);DFS(0, 0);printf("%.2f\n", Area(p, n) - min_);memset(vis, 0, sizeof(vis));}return 0;
}

POJ - Nice Milk(半平面交)相关推荐

  1. Feng Shui POJ - 3384 [半平面交]

    Feng Shui POJ - 3384 题意:n个顶点的凸包,放入2个半径为r的圆,可以重叠,要求面积最大,输出2个圆的圆心坐标(保留4位小数) 思路:找出圆心的可行域(内推r,求半平面交),再求核 ...

  2. POJ 3384 Feng Shui(半平面交)

    题意 : 给你一个凸多边形,让你在其中找两个圆,使得圆的覆盖面积最大. 这个题目和 poj 3525 有点类似,那个题目是一个圆,想到两者的联系,可以发现两个圆覆盖面积最大就是重叠面积最小,怎样使得重 ...

  3. POJ 1474 Video Surveillance(半平面交)

    题意:半平面交求多边形内核(我明明及的我之前是会用kuangbin第一份版平面交的,现在怎么就不会用了呢,补第二份代码) 代码: #include<cstdio> #include< ...

  4. poj 1755 Triathlon (半平面交解一元二次不等式)(切割求半平面交)

    题目链接:哆啦A梦传送门 参考链接:https://blog.csdn.net/acm_cxlove/article/details/7883370 半平面交模板 题目:铁人三项,每个人在某一项中有确 ...

  5. POJ - 3384 Feng Shui(半平面交)

    链接 Feng Shui 题意 将两个半径为 rrr 的圆放入一个多边形中,两个圆占据最大面积时圆心坐标是多少: 思路 在多边形中放圆,最大圆的圆心一定在多边形内核中: 将多边形的每条边都内推 rrr ...

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

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

  7. POJ 1474 Video Surveillance(半平面交)

    思路:半平面交裸题,要注意是顺时针给点. #include<iostream> #include<cstdio> #include<cstring> #includ ...

  8. (半平面交)POJ2451Uyuw‘s Concert

    POJ2451Uyuw's Concert 题意: 在一个 10000 × 10000 10000\times10000 10000×10000的正方形有 n n n条直线穿过,问左边半平面交所构成的 ...

  9. UVA1396 Most Distant Point from the Sea(AM - ICPC - Tokyo - 2007)(计算几何,半平面交 + 二分答案)

    整理的算法模板合集: ACM模板 题目传送门 见<训练指南>P279 很明显就是一个二分答案,它问的是最远的点,直接枚举因为这里都是double类型的数所以有无限个点,我们可以直接二分. ...

  10. LA 2218 (半平面交) Triathlon

    题意: 有n个选手,铁人三项有连续的三段,对于每段场地选手i分别以vi, ui 和 wi匀速通过. 对于每个选手,问能否通过调整每种赛道的长度使得他成为冠军(不能并列). 分析: 粗一看,这不像一道计 ...

最新文章

  1. 记录每个登陆用户的操作记录
  2. 【BIO】基于BIO实现简单动态HTTP服务器
  3. CentOS 5.5升级网卡驱动
  4. MySQL集群中主从切换
  5. 安川西格玛7驱动器手册_什么是伺服驱动器?选型的原则有哪些?
  6. 使用MFC开发ActiveX控件
  7. mybatis 配置文件中,collection 和 association 的对应关系
  8. S5PV210体系结构与接口11:NandFlash SD卡编程
  9. ROS 启动自带摄像头或者USB摄像头
  10. 现代软件工程 阅读笔记
  11. mysql count group by_MySQL中使用count与group by 的统计问题
  12. 从零开始学习Android Framework
  13. 麦克风声源定位原理_麦克风阵列原理及应用
  14. jsp+ssm计算机毕业设计学校缴费系统【附源码】
  15. unity 中是如何实现游戏人物换装的
  16. python 数据可视化工具 -- pyecharts
  17. redis哨兵模式搭建配置(一主三从三哨兵)
  18. Google搜索时如何在新标签页打开搜索结果
  19. 学 习 中 的 思 考
  20. 编写函数判断一个整数是否为素数

热门文章

  1. oracle12c性能测试,Oracle12c IMO 测试
  2. win10配置更新怎么关闭计算机,如何关闭win10系统自动更新功能?教你彻底关闭win10自动更新方法...
  3. 嵌入式系统开发-麦子学院(14)- uboot详解(1)
  4. python写的flappy bird小游戏(最简单版本)有视频链接
  5. android 6.0 vs ios9,安卓6.0彻底看呆!iOS 9安装率曝光 完胜
  6. 如何用python爬取豆瓣图书 Top 250
  7. 【Spring Security】Spring Boot + Spring Security 实现自动登录功能
  8. 计算机创新创业计划2000字,创新创业论文2000字
  9. matlab弦截法例子,弦截法matlab程序
  10. 用javascript的正则表达式来验证Email地址是否格式正确