hdu 4353 统计点在三角形内的个数

Finding Mine

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1120    Accepted Submission(s): 298

Problem Description

In bitland, there is an area with M gold mines.

As a businessman, Bob wants to buy just a part of the area, which is a simple polygon, whose vertex can only be chosen from N points given in the input (a simple polygon is a polygon without self-intersection). As a greedy man, he wants to choose the part with a lot of gold mines, but unluckily, he is short with money.

Those M gold mines can also be seen as points, but they may be different from those N points. You may safely assume that there will be no three points lying on the same line for all N+M points.

Bob alreadys knows that the price to buy an area is proportional to its size, so he changes his mind. Now he wants to buy a part like this: If the part‘s size is A, and contains B gold mines, then A/B will be minimum among all the possible parts he can choose. Now, please tell him that minimum number, if all the parts he can choose has B=0, just output -1.

Input

First line of the input is a single integer T(T<=30), indicating there are T test cases.
For each test case, the first line is two integers N(3<=N<=200) and M(1<=M<=500), the number of vertexs and the number of mines. Then N lines follows, the i-th line contains two integers xi,yi(-5000<=xi,yi<=5000), describing the position of the i-th vertex you can choose. Then M lines follow, the i-th line contains two integers xi,yi(-5000<=xi,yi<=5000), describing the position of the i-th mine.

Output

For each case, you should output “Case #k: ” first, where k indicates the case number between 1 and T. Then output the minimum A/B(rounded after the sixth decimal place) or -1.

Sample Input

3

3 1

0 0

0 2

3 0

1 1

4 2

0 0

0 5

5 0

2 2

1 2

2 1

3 1

0 0

0 2

2 0

2 2

Sample Output

Case #1: 3.000000

Case #2: 5.000000

Case #3: -1

Hint

For the second case, we can choose a polygon ( (0,0),(0,5),(2,2),(5,0) ) with A=10 and B=2, if we choose a
triangle ( (0,0),(0,5),(5,0) ), then A=12.5 and B=2.
For the third case, whatever we choose, we can‘t have a polygon contain the mines.

Author

[email protected]_Oblivion

Source

2012 Multi-University Training Contest 6

题目大意:给一个n可选取的顶点,m个金矿的坐标,求选取一个多边形它的面积与它所含金矿的个数的比值最少,找不到一个含有金矿的多边形的情况输出-1。

解题思路:可以证明一个最小比值的三角形(a/b)与其它三角形合起来形成的多边形肯定要大于a/b(a/b<min{a1/b1,a2/b2,...an/bn}时,a/b<(a+a1+a2..an)/(b+b1+b2+..+bn))。预处理每条直线上方金矿数量,那么三角形所含金矿数就等于abs(num[i][k]-num[i][j]-num[j][k])(画下图就知道了)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7
 8 const int maxn=505;
 9 const double eps=1e-8;
10 const double inf=1000000000.0;
11 int n,m,num[maxn][maxn];
12 struct Point
13 {
14     int x,y;
15     Point(int x=0,int y=0):x(x),y(y) {}
16 }a[maxn],b[maxn];
17 typedef Point Vector;
18 Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
19 int Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;}//叉积
20 inline double min(double a,double b){return a<b?a:b;}
21 bool compx(Point a,Point b){return a.x<b.x;}
22
23 void init()
24 {
25     for(int i=0;i<n;i++)
26     {
27         for(int j=i+1;j<n;j++)
28         {
29             int temp=0;
30             for(int k=0;k<m;k++)
31                 if(a[i].x<=b[k].x && b[k].x<a[j].x && Cross(a[j]-a[i],b[k]-a[i])>0)
32                     temp++;
33             num[i][j]=temp;
34         }
35     }
36 }
37
38 int main()
39 {
40     int i,j,k,t,icase=0;
41     scanf("%d",&t);
42     while(t--)
43     {
44         scanf("%d%d",&n,&m);
45         for(i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
46         sort(a,a+n,compx);
47         for(i=0;i<m;i++) scanf("%d%d",&b[i].x,&b[i].y);
48         init();
49         double ans=inf;
50         for(i=0;i<n;i++)
51         {
52             for(j=i+1;j<n;j++)
53             {
54                 for(k=j+1;k<n;k++)
55                 {
56                     int temp=abs(num[i][k]-num[i][j]-num[j][k]);
57                     if(temp==0) continue;
58                     ans=min(ans,fabs(Cross(a[j]-a[i],a[k]-a[i])/2.0)/temp);
59                 }
60             }
61         }
62         if(fabs(ans-inf)<eps) printf("Case #%d: -1\n",++icase);
63         else printf("Case #%d: %.6lf\n",++icase,ans);
64     }
65     return 0;
66 }

hdu 4353 统计点在三角形内的个数

时间: 2024-10-15 17:05:04

hdu 4353 统计点在三角形内的个数的相关文章

hdu 1251 统计难题 (map水过)

# include <stdio.h> # include <algorithm> # include <string.h> # include <map> # include <iostream> using namespace std; int main() { char a; string x; map<string,int>q; while(true) { scanf("%c",&a); if(a=

HDU 1251 统计难题 Trie题解

基本上是标准的寻找前缀的问题,只需要insert和search函数就可以了. 我这里主要是修改一下n的记录方法,这里的n代表的不是叶子节点的标志,而是有多少单词经过了这条路径的标志. 然后是查找需要查找的前缀单词,如果没有找到,就返回0,表示没有单词以这个前缀单词为前缀,如果找到,直接返回n就是答案了.因为有n个单词经过了这条路径. 查找效率是常数. 使用静态分配空间的办法. #include <stdio.h> #include <string.h> const int MAX_

统计一段时期内股票的涨幅情况

# -*- coding: utf-8 -*- """ 统计一段时期内股票的涨幅情况 """ '''导入模块''' import os import sqlalchemy import pandas '''清屏''' cls=os.system('cls') '''连接数据库''' engine = sqlalchemy.create_engine('mssql+pyodbc://sa:[email protected]') connection

华为oj 之 判断点是否在三角形内

/* * 任意顶点为A.B.C的三角形,如果点P在三角形内,那么 * 1)点P和点C在AB边的同一侧 2)点P和点A在BC边的同一侧 3)点P和点B在AC边的同一侧 * 反之亦然(充要条件) * * 关键:如何判断某两个点在某条直线的同一侧 * 参考图示发现: *   对于点P: AB*BC的方向 和 AB*BP的方向相同 *    对于点P1: AB*BC的方向 和 AB*BP1的方向不同 * 故:对于边AB,以及点C.P,如果AB*BC的方向 和 AB*BP的方向相同, *    那么点P和

均匀的生成圆和三角形内的随机点

代码在每一章节最后   一.均匀生成圆内的随机点 我们知道生成矩形内的随机点比较容易,只要分别随机生成相应的横坐标和纵坐标,比如随机生成范围[-10,10]内横坐标x,随机生成范围[-20,20]内的纵坐标y,那么(x,y)就是生成的随机点.由此,我们很容易的想到了算法1 算法1(正确的): 每个圆对应一个外切矩形,我们随机生成矩形内的点,如果该点在圆内,就返回改点,否则重新生成直到生成的点在圆内. 该方法的缺点是有可能连续几次都生成不了符合要求的点.(可以求得:每次生成点时,该点有 的概率在圆

[ACM] hdu 1251 统计难题 (字典树)

统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每一个提问都是一个字符串. 注意:本题仅仅有一组測试数据,处理到文件结束. Out

判断点是否在三角形内【转】

概述 给定三角形ABC和一点P(x,y,z),判断点P是否在ABC内.这是游戏设计中一个常见的问题.需要注意的是,这里假定点和三角形位于同一个平面内. 本文介绍三种不同的方法,由浅入深 一 内角和法 连接点P和三角形的三个顶点得到三条线段PA,PB和PC,求出这三条线段与三角形各边的夹角,如果所有夹角之和为180度,那么点P在三角形内,否则不在,此法直观,但效率低下. 二 同向法 假设点P位于三角形内,会有这样一个规律,当我们沿着ABCA的方向在三条边上行走时,你会发现点P始终位于边AB,BC和

判断点是否在三角形内

http://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html#!comments 本文只是翻译和整理,原文在此http://www.blackpawn.com/texts/pointinpoly/default.html 概述 给定三角形ABC和一点P(x,y,z),判断点P是否在ABC内.这是游戏设计中一个常见的问题.需要注意的是,这里假定点和三角形位于同一个平面内. 本文介绍三种不同的方法,由浅入深 一 内角和法 连接点P和三

2D空间中判断一点是否在三角形内

本来打算做三角形填充多边形,但需要用到耳切法正在看.所以先研究了这个 要注意如果是XY坐标轴的2D空间,要取差乘分量z而不是y. 实现原理是,将三角形ABC三个边(AB,BC,CA)分别与比较点判断差乘,如果这3个差乘结果表示的方向一致,说明就在三角形内. 效果: 代码(Unity3D): using UnityEngine; using System.Collections; using System.Collections.Generic; public class TriangleColl