51Nod 1976 多邊形劃分

2021-08-21 06:17:41 字數 1904 閱讀 6159

(一)題面:

1976 多邊形劃分

給乙個共有 n

個點的凸多邊形,求一條將該多邊形劃分為面積和周長都相等的兩部分

的直線。

input

第一行乙個正整數n,表示多邊形的點數。(n <= 40000)

接下來的n行,第i+1行,每行兩個實數xi,yi,表示凸多邊形的乙個點的座標,點按照逆時針或順時針的順序給出。

其中n,|xi|,|yi|<=40000。

output

如果存在這樣的直線,將這條直線與凸多邊形的兩個交點的座標分兩行輸出。你所求的直線必須與多邊形有兩個交點,且分多邊形的兩部分周長或面積相差都不能大於10^-3。

如果不存在,輸出"impossible"(不含引號)。

input示例

4

0 03 0

3 30 3

output示例

1 0

2 3

(二)題目大意:

見題面qaq.

(三)解題思路:

像我這麼菜當然是沒想到思路的啦~...

下面是官方題解:

①首先,我們對這條直線的存在性進行證明。

在凸多邊形上任取一點  p ,定義函式 f(x) :設凸多邊形周長為 c  ,從 p 點出發在凸多邊形上沿順時

針方向移動 x 個單位長度後,設到達的點為q1,從p+c/2點出發沿著凸多邊形移動x個單位長度後到達 q2

,函式值為射線 q1q2 兩側的面積差。不難發現有 f(x)=−f(x+c2) ,因為此時射線剛好翻轉。根據零點存

在定理可知在區間 [0,c2]存在一實數 x0 使得 f(x0)=0 ,證畢。

②存在性得到證明後,只需求解出函式的乙個零點即可。可採用二分法求出零點。顯然零點可能並不一定唯

一,但我們只需求出乙個零點,二分法仍然適用,只需在縮小區間的時候保證區間內一定存在乙個零點即可

(設當前考慮的區間為[l,r],只需保證f(l)與f(r)異號)。至此演算法便水落石出了。

③演算法的時間複雜度為 o(nlogc)。

其圖示如下:

設:f(x)=s1-s2,則f(x+c/2)=s2-s1,又因為f(x)是連續的,所以有了題解中的結論,然後二分求零點即

可。(四)具體**:

#include#include#include#include#include#include#define id (sp+1)%n

using namespace std;

const int maxn=4e4+10;

struct point

point(double _x,double _y)

}p[maxn];

double dist(point a,point b)

double area(point a,point b,point c)

const double esp=1e-9;

point getp(point a,point b,double x)

double fx(double x,double c,double s,int n){//求f(x)

int sp=0;

double d;

while((d=dist(p[sp],p[id]))(五)總結一下:

①計算幾何往往需要去尋找一些重要的數學關係。

②這裡被卡了精度,真是#¥%……&*,我那裡二分判斷的條件貌似不是很「標準」,然後輸出小數的位數

要夠多,貌似計算幾何問題裡面涉及到精度的問題還不少...。

③照著題解的思路寫,**寫得比較難看...有待改進。

劃分凸多邊形

時間限制 800ms 記憶體限制 65535k 提交次數 0 通過次數 0 題型 程式設計題 語言 g gcc vc 問題描述 乙個正凸n邊形,可以用n 3條互不相交的對角線將正n邊形分成n 2個三角形。現在要求讀入n邊形的n n 20 輸出不同劃分方法的總數 要求解的是劃分方法數,而不需要輸出各種...

凸多邊形的劃分

給定乙個具有 n 個頂點的凸多邊形,將頂點從 1 至 n 標號,每個頂點的權值都是乙個正整數。將這個凸多邊形劃分成 n 2 個互不相交的三角形,對於每個三角形,其三個頂點的權值相乘都可得到乙個權值乘積,試求所有三角形的頂點權值乘積之和至少為多少。輸入格式 第一行包含整數 n,表示頂點數量。第二行包含...

凸多邊形的劃分

給定乙個具有 n 個頂點的凸多邊形,將頂點從 1 至 n 標號,每個頂點的權值都是乙個正整數。將這個凸多邊形劃分成 n 2 個互不相交的三角形,對於每個三角形,其三個頂點的權值相乘都可得到乙個權值乘積,試求所有三角形的頂點權值乘積之和至少為多少。輸入格式 第一行包含整數 n,表示頂點數量。第二行包含...