1. 程式人生 > >ACM-計算幾何之Scrambled Polygon——poj2007

ACM-計算幾何之Scrambled Polygon——poj2007

Scrambled Polygon

Time Limit: 1000MS Memory Limit: 30000K

Total Submissions: 6513 Accepted: 3092

Description
A closed polygon is a figure bounded by a finite number of line segments. The intersections of the bounding line segments are called the vertices of the polygon. When one starts at any vertex of a closed polygon and traverses each bounding line segment exactly once, one comes back to the starting vertex.

A closed polygon is called convex if the line segment joining any two points of the polygon lies in the polygon. Figure 1 shows a closed polygon which is convex and one which is not convex. (Informally, a closed polygon is convex if its border doesn't have any "dents".)


The subject of this problem is a closed convex polygon in the coordinate plane, one of whose vertices is the origin (x = 0, y = 0). Figure 2 shows an example. Such a polygon will have two properties significant for this problem.

The first property is that the vertices of the polygon will be confined to three or fewer of the four quadrants of the coordinate plane. In the example shown in Figure 2, none of the vertices are in the second quadrant (where x < 0, y > 0).

To describe the second property, suppose you "take a trip" around the polygon: start at (0, 0), visit all other vertices exactly once, and arrive at (0, 0). As you visit each vertex (other than (0, 0)), draw the diagonal that connects the current vertex with (0, 0), and calculate the slope of this diagonal. Then, within each quadrant, the slopes of these diagonals will form a decreasing or increasing sequence of numbers, i.e., they will be sorted. Figure 3 illustrates this point.


Input
The input lists the vertices of a closed convex polygon in the plane. The number of lines in the input will be at least three but no more than 50. Each line contains the x and y coordinates of one vertex. Each x and y coordinate is an integer in the range -999..999. The vertex on the first line of the input file will be the origin, i.e., x = 0 and y = 0. Otherwise, the vertices may be in a scrambled order. Except for the origin, no vertex will be on the x-axis or the y-axis. No three vertices are colinear.

Output

The output lists the vertices of the given polygon, one vertex per line. Each vertex from the input appears exactly once in the output. The origin (0,0) is the vertex on the first line of the output. The order of vertices in the output will determine a trip taken along the polygon's border, in the counterclockwise direction. The output format for each vertex is (x,y) as shown below.

Sample Input
0 0
70 -50
60 30
-30 -50
80 20
50 -60
90 -20
-30 -40
-10 -60

90 10

Sample Output
(0,0)
(-30,-40)
(-30,-50)
(-10,-60)
(50,-60)
(70,-50)
(90,-20)
(90,10)
(80,20)

(60,30)

計算幾何,給出一系列點,按照極角排序。

應該屬於Graham求凸包的前置題目吧。。。

很基礎。注意輸入時判定停止。

在注意一下精度,應該就OK了,

說一下極角排序幾種方法吧,這些都是看人家Blog。

1.利用叉積的正負來作cmp.(即是按逆時針排序).此題就是用這種方法

double cross(point p0,point p1,point p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
// sort排序函式
bool cmp(const point &a, const point &b)//逆時針排序
{
    point origin;
    // 設定原點
    origin.x = origin.y = 0;
    return cross(origin,b,a)<EPS;
}

2.利用complex的內建函式。

#include<complex>
#define x real()
#define y imag()
#include<algorithm>
using namespace std;

bool cmp(const Point& p1, const Point& p2)
{
    return arg(p1) < arg(p2);
}

3.利用arctan計算極角大小。(範圍『-180,180』)

bool cmp(const Point& p1, const Point& p2)
{     
    return atan2(p1.y, p1.x) < atan2(p2.y, p2.x);
}

4.利用象限加上極角,叉積。

bool cmp(const point &a, const point &b)//先按象限排序,再按極角排序,再按遠近排序 
{
    if (a.y == 0 && b.y == 0 && a.x*b.x <= 0)return a.x>b.x;
    if (a.y == 0 && a.x >= 0 && b.y != 0)return true;
    if (b.y == 0 && b.x >= 0 && a.y != 0)return false;
    if (b.y*a.y <= 0)return a.y>b.y;
    point one;
    one.y = one.x = 0;
    return cross(one,a,one,b) > 0 || (cross(one,a,one,b) == 0 && a.x < b.x);    
}

恩,就是這些啦~
/**************************************
***************************************
*        Author:Tree                 *
*From  :http://blog.csdn.net/lttree  *
* Title : Scrambled Polygon           *
*Source: poj 2007                     *
* Hint  : 凸包                        *
***************************************
**************************************/
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
#define EPS 1e-8
struct point
{
    double x,y;
}p[51];

double cross(point p0,point p1,point p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
// sort排序函式
bool cmp(const point &a, const point &b)//逆時針排序
{
    point origin;
    // 設定原點
    origin.x = origin.y = 0;
    return cross(origin,b,a)<EPS;
}
int main()
{
    int i,n;
    n=0;
    while( scanf("%lf%lf",&p[n].x,&p[n].y)!=EOF )
    {
        ++n;
    }
    // 極角排序,第一個空過去
    sort(p+1,p+n,cmp);

    for(i=0;i<n;++i)
        printf("(%.0lf,%.0lf)\n",p[i].x,p[i].y);

    return 0;
}



相關推薦

ACM-計算幾何Scrambled Polygon——poj2007

Scrambled Polygon Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6513 Accepted: 3092 Description A closed polygon is a figur

ACM-計算幾何Segments——poj3304

Segments Description Given n segments in the two dimensional space, write a program, which determines if there exists a line such that af

1015 - 計算幾何點與多邊形的關係 - Points Within(ZOJ1081)

傳送門   分析 射線法 雖然這個射線法有很多需要特判的情況,但總的來說還是蠻好用的 判斷點與多邊形的關係,若使用射線法,就是說從這個點往右做一條與 x 軸平行的射線,看它與多邊形相交了幾次 若相交了偶數次,則不在多邊形內部(相當於從這個多邊形中穿過去,沒有留在

1015 - 計算幾何旋轉卡殼 - Beauty Contest(POJ 2187)

傳送門   題意 給定 n 個點,求最遠點對,並輸出其距離的平方   分析 首先我們先來把這  n 個點圍出一個凸包來 由於最遠點對肯定不會在凸包內部啊,所以我們就在凸包邊上找找找找找 用一個叫做旋轉卡殼的演算法,我們可以在凸包頂點數

1015 - 計算幾何Graham掃描法求凸包 - Cows(POJ 3348)

傳送門   題意 給你一堆點,求這些點的凸包,並求出面積   分析 很久之前就做過的一道題了,還記得那是凱爺(凱爺好厲害好厲害的)講的,是Jarris步進法:按照橫縱座標對所有的點進行排序(橫座標優先) 然後就是和Graham類似的方法了,邊掃描邊

1015 - 計算幾何多邊形的面積 - Build Your Home(POJ 3907)

傳送門   題意 順時針或逆時針給出多邊形的頂點,求該多邊形的面積   分析 很基礎…… 利用叉積的性質,每次選擇相鄰的兩個點做叉積,把答案累加起來 由於方向的問題,最後要取一個絕對值 又因為叉積算的是平行四邊形的面積,所以還要除以2

1015 - 計算幾何直線與直線的關係 - Intersecting Lines(POJ1269)

傳送門   題意 給你兩條直線 若其相交則輸出  交點的座標 若其平行則輸出  NONE 若其重合則輸出  LINE   分析 比較基礎的計算幾何,就是考向量的使用 判斷兩條直線是否平行,就是看其叉積是否為

1016 - 計算幾何點與直線的關係 - TOYS(POJ 2318)

傳送門   題意 給你一個這樣的圖 然後隨機給你 m 個點,問落在每一個區域內的點有多少個   分析 入門題入門題 依舊是利用叉積,叉積太強了! 二分尋找並判斷     gsj太厲害了,簡直每次我演算法

1018 - 計算幾何凸包 - 水平可見直線(BZOJ 1007)

傳送門   分析 遇到新的題,要思考著往學過的模型上套 這道題要求的是水平可見直線,其實稍微轉化一下,就會發現最後能夠被看見的直線恰好形成了一個開口向上的半凸包的樣子 我們畫出一個半凸包,可以發現每條邊的斜率是在從左往右依次增加,而其交點橫座標的大小也在遞增 可

1016 - 計算幾何直線與線段的交 - Segments(POJ 3304)

傳送門   題意 雖然題目是給了什麼投影啊,什麼奇奇怪怪的東西 但實際上也就是給你 n 條線段,詢問是否存在一條直線能經過所有的線段 資料範圍:n<=100   分析 這個資料範圍有點友好啊…… 我們先來想一個問題 若存在一條直線

1018 - 計算幾何多邊形面積 - 改革春風吹滿地 (HDU 2036)

傳送門   分析 sb題 主要是題面太皮,我才去做的:) 簡單的多邊形面積,用叉積即可   程式碼 #include<bits/stdc++.h> #define in read() #define N 105 using name

ACM計算幾何總結

文章目錄 1 幾何基礎 2 點與向量 2.1 手動實現 2.2 複數黑科技 3 點與線 3.1 直線定義 3.2 求兩直線交點 3.3 求點到直線距離 3.4 求點到線段距離 3

ACM 計算幾何總結

1 幾何基礎 #include <cstdio> #include <cmath> using namespace std; const double pi = acos(-1.0); const double inf = 1e100; con

計算幾何凸包----Graham掃描法

計算幾何之凸包(convexHull)----Graham掃描法 關於凸包的嚴格定義,這裡不打算寫出來,大家可以自行Google或者百度,因為嚴格的數學定義反而不太好理解,用最通俗的話來解釋凸包:給定

我的計算幾何

            計算幾何之路 計算幾何 Part.1---點,線,面,形基本關係,點積叉積的理解 計算幾何 Part.2---凸包問題 計算幾何 Part.3---面積公式矩形切割 計算幾何 Part.4---半平面交 計算幾何 Part.5---計算幾何背景,實

ACM計算幾何--三角形問題

#include <math.h> struct point{double x,y;}; struct line{point a,b;}; double distance(point p1,point p2){ return s

ACM計算幾何題目推薦

Part.1---點,線,面,形基本關係,點積叉積的理解 Part.2---凸包 面積 公式 矩形切割 Part.3---半平面交 Part.4---雜題 解析幾何 旋轉卡殼 綜合問題 Part.5---。。。。。 Part.6---三維幾何 ========

計算幾何基礎篇

向量 AB−→−表示一個從點A到點B的向量。 向量滿足: 加法的交換性:a⃗ +b⃗ =b⃗ +a⃗  加法的結合性:(a⃗ +b⃗ )+c⃗ =a⃗ +(b⃗ +c⃗ ) 加法恆等式:0⃗ +a⃗ =a⃗  對於一個實數k,有ka⃗ 的方向與a

ACM計算幾何

Computational Geometry 計算幾何     ACM中基本是最麻煩的部分。     幾何程式碼都要自己寫,STL中也沒有。基本上。     struct point  

計算幾何旋轉卡殼演算法

一些歷史: 1978年, M.I. Shamos's Ph.D. 的論文"Computational Geometry"標誌著電腦科學的這一領域的誕生。 當時他發表成果的是一個尋找凸多邊形直徑的一個非常簡單的演算法, 即根據多邊形的一對點距離的最大值來確定。  後來直徑演化為由一對對踵點對來確定。 Sham