思路来自于:http://www.cnblogs.com/wuyiqi/archive/2011/11/06/2238530.html

枚举两个多边形的两个点组成的直线,判断能与几个多边形相交

因为最佳的直线肯定可以经过某两个点(可以平移到顶点处),所以暴力枚举两个点就好了

如果有模版的话,写代码就快多了。

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map> #define LL long long
#define eps 1e-8
#define N 15
#define K 15 using namespace std; struct Point{
double x, y;
Point operator - (const Point &t) const
{
Point temp;
temp.x = x-t.x;
temp.y = y-t.y;
return temp;
}
Point operator + (const Point &t) const
{
Point temp;
temp.x = x+t.x;
temp.y = y+t.y;
return temp;
}
bool operator == (const Point &t) const
{
return fabs(x-t.x)<eps&&fabs(y-t.y)<eps;
}
};
struct Figure{
int cnt;
Point poi[K];
};
struct Line{
double a, b, c;
};
Figure fig[N];
Line t_Line(Point a, Point b)//点到直线的转化
{
Line temp;
temp.a = a.y-b.y;
temp.b = b.x-a.x;
temp.c = a.x*b.y-b.x*a.y;
return temp;
}
bool Line_Inst(Line l1, Line l2, Point &p)//判断直线相交,并求交点
{
double a1 = l1.a, b1 = l1.b, c1 = l1.c;
double a2 = l2.a, b2 = l2.b, c2 = l2.c;
if(fabs(a1*b2-a2*b1)<eps) return false;
p.x = (b1*c2-b2*c1)/(a1*b2-a2*b1);
p.y = (a1*c2-a2*c1)/(a2*b1-a1*b2);
return true;
}
double cross(Point a, Point b, Point c)//求向量的叉积,判断三点是否共线
{
return (b.x-c.x)*(a.y-c.y)-(b.y-c.y)*(a.x-c.x);
}
bool dotOnSeg(Point a, Point b, Point c)//判断点是否在线段上
{
if(a==c||b==c) return true;
return cross(a,b,c)<eps&&
(b.x-c.x)*(a.x-c.x)<eps&&
(b.y-c.y)*(a.y-c.y)<eps;
}
int main ()
{
int t, n, k, kk = 0;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &k);
fig[i].cnt = k;
for(int j = 1; j <= k; ++j)
scanf("%lf %lf", &fig[i].poi[j].x, &fig[i].poi[j].y);
}
if(n<=2)
{
printf("Case %d: %d\n",++kk, n);
continue;
}
int ans = 0;
Point p;
for(int i = 1; i <= n; ++i)
for(int j = i+1; j <= n; ++j)
for(int k = 1; k <= fig[i].cnt; ++k)
for(int l = 1; l <= fig[j].cnt; ++l)
{
Line l1 = t_Line(fig[i].poi[k], fig[j].poi[l]);//找到经过两个图形的顶点的直线
int tt = 2;
for(int ii = 1; ii <= n; ++ii)
{
if(ii==i||ii==j) continue;
for(int jj = 1; jj < fig[ii].cnt; ++jj)
{
Line l2 = t_Line(fig[ii].poi[jj], fig[ii].poi[jj+1]);//图形的两个相邻节点组成一条直线
if(Line_Inst(l1,l2,p)&&dotOnSeg(fig[ii].poi[jj], fig[ii].poi[jj+1], p))
{//直线相交,并且交点位于线段上,即可证明直线l1穿过线段
++tt;
break;
}
}
}
ans = max(ans, tt);
}
printf("Case %d: %d\n",++kk, ans);
}
return 0;
}

hdu - 3952 Fruit Ninja(简单几何)的更多相关文章

  1. hdu 4000 Fruit Ninja 树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000 Recently, dobby is addicted in the Fruit Ninja. ...

  2. hdu 4620 Fruit Ninja Extreme

    Fruit Ninja Extreme Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. HDU 4620 Fruit Ninja Extreme 搜索

    搜索+最优性剪枝. DFS的下一层起点应为当前选择的 i 的下一个,即DFS(i + 1)而不是DFS( cur + 1 ),cur+1代表当前起点的下一个.没想清楚,TLE到死…… #include ...

  4. HDU 4116 Fruit Ninja

    http://acm.hdu.edu.cn/showproblem.php?pid=4116 题意:给N个圆,求一条直线最多能经过几个圆?(相切也算) 思路:枚举中心圆,将其他圆的切线按照极角排序,并 ...

  5. HDU 4000 Fruit Ninja 树状数组 + 计数

    给你N的一个排列,求满足:a[i] < a[k] < a[j] 并且i < j < k的三元组有多少个. 一步转化: 求出所有满足 a[i] < a[k] < a[ ...

  6. HDU 4620 Fruit Ninja Extreme(2013多校第二场 剪枝搜索)

    这题官方结题报告一直在强调不难,只要注意剪枝就行. 这题剪枝就是生命....没有最优化剪枝就跪了:如果当前连续切割数加上剩余的所有切割数没有现存的最优解多的话,不需要继续搜索了 #include &l ...

  7. hdu 4620 Fruit Ninja Extreme(状压+dfs剪枝)

    对t进行从小到大排序(要记录ID),然后直接dfs. 剪枝的话,利用A*的思想,假设之后的全部连击也不能得到更优解. 因为要回溯,而且由于每次cut 的数目不会超过10,所以需要回溯的下标可以利用一个 ...

  8. HDU 4620 Fruit Ninja Extreme 暴搜

    题目大意:题目就是描述的水果忍者. N表示以下共有 N种切水果的方式. M表示有M个水果需要你切. W表示两次连续连击之间最大的间隔时间. 然后下N行描述的是 N种切发 第一个数字C表示这种切法可以切 ...

  9. HDU 4000 Fruit Ninja (树状数组+反向思维)

    题意:给你一串数且每个数都不同,问你(x,y,z)出现 x<z<y 的总次数 首先我们直接想的话不能使用O(n*log2 n)解决,所以可以正难则反 可以求得x<(y,z)的值,减去 ...

随机推荐

  1. Oracle 增加修改删除字段与添加注释

    添加字段的语法:alter table tablename add (column datatype [default value][null/not null],….); 修改字段的语法:alter ...

  2. uva 10340 All in All

    水题,从头到尾扫一遍就可以了,输入两个字符串s和t,判断是否可以从t中删除0个或多个字符(其他字符顺序不变),得到字符串s.例如,abcde可以得到bce,但无法得到dc. #include<a ...

  3. gsons

    java 处理 json格式字符串,目前只使用过Google的Gson库. pom: <dependency> <groupId>com.google.code.gson< ...

  4. 并查集(HDOJ 1856)

    并查集   英文:Disjoint Set,即“不相交集合” 将编号分别为1…N的N个对象划分为不相交集合, 在每个集合中,选择其中某个元素代表所在集合. 常见两种操作: n       合并两个集合 ...

  5. 一步一步搭建Jenkins环境

    Jenkins使用经验谈1(一步一步搭建Jenkins环境)在公司使用 Jenkins 软件已经有一段时间了,走了很多弯路,但也积累了一些经验,可以和大家分享一下.我们来一起搭建Jenkins环境.首 ...

  6. 转Web安全测试之XSS

    转http://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html XSS 全称(Cross Site Scripting) 跨站脚本攻击 ...

  7. machine learning----->什么是机器学习

    1.概述: 学习一门学问的第一步就是要了解这门学问到底是什么,它可以被用来干什么. 本文罗列了学习machine learning的过程中看到的一些写得比较好的文章以及读完这些文章之后对机器学习的初步 ...

  8. java1.7集合源码阅读:LinkedList

    先看看类定义: public class LinkedList<E> extends AbstractSequentialList<E> implements List< ...

  9. easyul获取各种属性ID 和赋值

    //span赋值 $('#state1').text("审核通过"); //textarea赋值 $("#memo").val('');  //隐藏域 $(&q ...

  10. C# webApi 与 AngularJs 实现增删改Demo 讲解(一)

    公司在使用webAPI+AngularJs+SlcikGrid进行产品开发,自己也是初学Angular,就做了一个Demo,实现增删改功能,希望可以帮助大家. 界面如同所示:  数据库一张单表很简单, ...