HDOJ 1115 Lifting the Stone (計算幾何+多邊形重心)

原題鏈接

一、題目描述

Problem Description
There are many secret openings in the floor which are covered by a big heavy stone. When the stone is lifted up, a special mechanism detects this and activates poisoned arrows that are shot near the opening. The only possibility is to lift the stone very slowly and carefully. The ACM team must connect a rope to the stone and then lift it using a pulley. Moreover, the stone must be lifted all at once; no side can rise before another. So it is very important to find the centre of gravity and connect the rope exactly to that point. The stone has a polygonal shape and its height is the same throughout the whole polygonal area. Your task is to find the centre of gravity for the given polygon. 
 

Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer N (3 <= N <= 1000000) indicating the number of points that form the polygon. This is followed by N lines, each containing two integers Xi and Yi (|Xi|, |Yi| <= 20000). These numbers are the coordinates of the i-th point. When we connect the points in the given order, we get a polygon. You may assume that the edges never touch each other (except the neighboring ones) and that they never cross. The area of the polygon is never zero, i.e. it cannot collapse into a single line. 
 

Output
Print exactly one line for each test case. The line should contain exactly two numbers separated by one space. These numbers are the coordinates of the centre of gravity. Round the coordinates to the nearest number with exactly two digits after the decimal point (0.005 rounds up to 0.01). Note that the centre of gravity may be outside the polygon, if its shape is not convex. If there is such a case in the input data, print the centre anyway. 
 

Sample Input
2 4 5 0 0 5 -5 0 0 -5 4 1 1 11 1 11 11 1 11
 

Sample Output
0.00 0.00 6.00 6.00

二、題目分析

題目直截了當要求重心。所以,直接按照多邊形的求解模版即可。不過,這題的OJ(如HDOJ)默認所有測試用例都是逆時針輸入的,方便了求解面積,且爲正向面積。減輕了很大一部分工作。直接依次算出每個子三角形的重心和麪積即可。然後算出多邊形的重心。

這裏說的比較簡陋,如果第一次接觸計算幾何。可以百度/goole一下,抓住向量叉積在計算幾何中的應用。如判斷線段相交、三角形面積、多邊形面積、多邊形重心、土包(凸包)。

如果,多邊形的各頂點不是按照逆時針輸入的,那麼就不能按照下面的代碼求解了。還需coder自己按照逆時針或順時針重新排列各定點。


三、AC代碼

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

struct Point
{
	double x, y;
};
int cas, n;
double Area(Point p0, Point p1, Point p2)
{
	double area = 0;
    area = (p1.x - p0.x)*(p2.y - p1.y) -(p2.x - p1.x)*(p1.y - p0.y);  // cross products.
    return area/2;
    //return area;  // actually, area should be divided by 2, but this problem, both is ok.
}
int main()
{
	Point p0, p1, p2;
	double sum_x, sum_y, sum_area, area;
	scanf("%d", &cas);
	while (cas--)
	{
		sum_x = sum_y = sum_area = 0;
		scanf("%d", &n);
		scanf("%lf%lf", &p0.x, &p0.y);
		scanf("%lf%lf", &p1.x, &p1.y);
		for (int i = 2; i < n; ++i)
		{
			scanf("%lf%lf", &p2.x, &p2.y);
			area = Area(p0, p1, p2);
			sum_area += area;
			sum_x += (p0.x + p1.x + p2.x) * area;
			sum_y += (p0.y + p1.y + p2.y) * area;
			p1 = p2;
		}
		printf("%.2lf %.2lf\n", sum_x / sum_area / 3, sum_y / sum_area / 3);
	}
	return 0;
}


發佈了40 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章