E. Coin Tossing 第八届北京邮电大学程序设计竞赛 - 热身赛 (2)
题目描述
Little smart QiQi is fond of coin tossing. This day, he came to a huge field, where there's a irregular convex swamp within. Little smart QiQi didn’t want to toss the coin into the swamp, and thus, she needed to know the area of this convex. Please help her.
输入格式
The input contains several test cases, ended with EOF. In each test case, an integer N(3≤N≤100) exists first, indicating the number of vertex. The following N lines give the coordinates(x,y) of each vertex.(−106≤x,y≤106), x and y are real numbers.
输出格式
Output the area of each convex. The answer should be corrected to 1 decimal places.
输入样例
3
-1 0
0 1
1 1
输出样例
0.5
思路:计算多边形最低点 -》 将多边形移动到最低点刚好为原点 -》 计算各个顶点和原点连线的cos值,最低点赋特殊值(10)-》所有顶点按照cos值排序
-》依次计算相临两点与最低点形成的三角形的面积(公式:s = 1/2*跟号下(p(p-a)(p-b)(p-c))(其中:abc是三角形三条边))-》 将所有的这样的三
角形面积相加即得到凸多边形的面积
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <stdlib.h>
using namespace std;
struct node {
double x;
double y;
double cos;
};
//移动多边形
void move(vector<node> &org)
{
double xx = org[0].x;
double yy = org[0].y;
for (int i = 0; i < org.size(); ++i) {
if (org[i].y < yy) {
yy = org[i].y;
xx = org[i].x;
}
}
for (int j = 0; j < org.size(); ++j) {
org[j].x -= xx;
org[j].y -= yy;
}
cout << "move up " << endl;
for (int j = 0; j < org.size(); ++j) {
cout << org[j].x << " " << org[j].y << endl;
}
}
//排序比较规则
bool comp(const node &s1, const node &s2)
{
return s1.cos < s2.cos;
}
void countCosAndSort(vector<node> &org)
{
for (int i = 0; i < org.size(); ++i) {
if ((org[i].y < 0.000001 || org[i].y > -0.000001) &&
(org[i].x < 0.000001 || org[i].x > -0.000001)) {
org[i].cos = 10;
continue;
}
double d = sqrt(org[i].x * org[i].x + org[i].y * org[i].y);
org[i].cos = org[i].x / d;
}
sort(org.begin(), org.end(), comp);
cout << "after sort" << endl;
for (int i = 0; i < org.size(); ++i) {
cout << org[i].x << " " << org[i].y << endl;
}
}
//计算单个三角形面积
double singleArea(node &n1, node &n2)
{
double len1, len2, len3;
len1 = sqrt(n1.x * n1.x + n1.y * n1.y);
len2 = sqrt(n2.x * n2.x + n2.y * n2.y);
len3 = sqrt((n2.x-n1.x)*(n2.x-n1.x) + (n2.y-n1.y)*(n2.y-n1.y));
double p = (len1+len2+len3)/2;
double s = sqrt(p*(p-len1)*(p-len2)*(p-len3));
return s;
}
//计算多边形面积
double sunArea(vector<node> &org)
{
move(org);
countCosAndSort(org);
double sumA = 0;
for (int i = 0; i < org.size()-1; ++i) {
sumA += singleArea(org[i], org[i+1]);
}
return sumA;
}
int main()
{
int t;
cin >> t;
vector<node> data;
node tmp;
double xx, yy;
for (int i = 0; i < t; ++i) {
cin >> xx >> yy;
tmp.x = xx;
tmp.y = yy;
data.push_back(tmp);
}
cout << sunArea(data) << endl;
return 0;
}