HDU-2108-Shape of HDU(Java+向量叉乘的简单应用)

来源:互联网 发布:文明5 mac 下载 编辑:程序博客网 时间:2024/05/14 19:36

Shape of HDU

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5575    Accepted Submission(s): 2531


Problem Description
话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,“徐队”的称呼逐渐被“徐总”所取代,海东集团(HDU)也算是名副其实了。
创业是需要地盘的,HDU向钱江肉丝高新技术开发区申请一块用地,很快得到了批复,据说这是因为他们公司研发的“海东牌”老鼠药科技含量很高,预期将占全球一半以上的市场。政府划拨的这块用地是一个多边形,为了描述它,我们用逆时针方向的顶点序列来表示,我们很想了解这块地的基本情况,现在请你编程判断HDU的用地是凸多边形还是凹多边形呢?
 

Input
输入包含多组测试数据,每组数据占2行,首先一行是一个整数n,表示多边形顶点的个数,然后一行是2×n个整数,表示逆时针顺序的n个顶点的坐标(xi,yi),n为0的时候结束输入。
 

Output
对于每个测试实例,如果地块的形状为凸多边形,请输出“convex”,否则输出”concave”,每个实例的输出占一行。
 

Sample Input
40 0 1 0 1 1 0 10
 

Sample Output
convex海东集团终于顺利成立了!后面的路,他们会顺顺利利吗?欲知后事如何,且听下回分解——
 

Author
lcy
 

Source
ACM程序设计_期末考试(时间已定!!)
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  1086 1392 1115 2111 2110 


遇到这种题,要一步一步思考来,切忌操之过急!
首先我们要明确凸多边形的定义是:所谓凸多边形,就是把一个多边形任意一边向两方无限延长成为一条直线,如果多边形的其他各边均在此直线的同旁,那么这个多边形就叫做凸多边形。

这时如果按照一般的数学思路来想,我第一个想到的思路是,任选多边形两顶点,写出这两点的直线方程,在将除那两点之外的所有点都带进未知数x,y进行计算,看所有结果是否同号(正负号),如果同号则其他顶点都在该直线的同侧,为凸多边形,如果异号则为凹多边形.
这个思路没有错,但是实现起来太繁琐了,感兴趣的童鞋可以自己试试!但是我们也可以想想有没有更加好的方法呢?

解题思路: 叉乘的运用
原理是在平面上去(0,0)来分割多边形为多个三角形,然后用叉乘来求三角形的面积(有向)再求和。这样的话可以把凸N多边形转化为N-2个三角形,然后求解N个三角形即可,输入定点的顺序,无论逆时针还是顺时针都行!


/* * 向量点积:两个向量的点积为标量,A向量*B向量=A*B*cosa; * 向量叉积:两个向量的叉积是向量,它们的绝对值相当于两个向量构成平行四边形的面积,A向量*B向量=A*B*sina; * 相当于三角形的2倍,然后我们可以利用三角形的面积的正负来判断是否是凸边形.因为如果是凹边形,a>90度小于180度, * sina<0,得出的结果一定为负数! */import java.awt.Point;import java.io.*;import java.util.*;public class Main{public static class Spot{int x, y;}public static int CrossProduct(int x1, int x2, int y1, int y2){return x1 * y2 - x2 * y1;}public static void main(String[] args){// TODO Auto-generated method stubScanner input = new Scanner(System.in);while (input.hasNext()){int n = input.nextInt();int ans = 0;if (n == 0)break;Spot a[] = new Spot[n + 2];for (int i = 0; i < n; i++){a[i] = new Spot();a[i].x = input.nextInt();a[i].y = input.nextInt();}a[n] = a[0];a[n + 1] = a[1];for (int i = 2; i <= n + 1; i++){int x1 = a[i - 1].x - a[i - 2].x;int y1 = a[i - 1].y - a[i - 2].y;int x2 = a[i].x - a[i - 1].x;int y2 = a[i].y - a[i - 1].y;ans = CrossProduct(x1, x2, y1, y2);if (ans < 0)break;}if (ans < 0)System.out.println("concave");else{System.out.println("convex");}}}}


 

0 0