生活随笔
收集整理的這篇文章主要介紹了
bzoj2146 Construct
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
隨著改革開放的深入推進…… 小T家要拆遷了…… 當對未來生活充滿美好憧憬的小T看到拆遷協議書的時候,小T從一位大好的社會主義青年變成了絕望的釘子戶。 由于小T的家位于市中心,拆遷工作又難以進行,有關部門決定先把小T家用圍欄圍起來,以免影響市容。考慮到要建設資源節約型社會,他們希望所用的圍欄長度越短越好,由于市中心寸土寸金,在圍欄長度最短的情況下,圍出的多邊形面積越小越好。 為了簡化問題,我們約定,小T的家是一個多邊形,并且每條邊與坐標軸平行,圍欄構成的也是多邊形,每條邊與坐標軸平行。?
輸入格式
在第一行列出整數n——多邊形的頂點的數量。在以下n行中的每一行都有兩個整數——沿逆時針方向走過這個多邊形順次所經過的頂點的坐標。邊界的任意三個連續頂點不在一條直線上。多邊形的邊界不含自交和自切。
輸出格式
輸出兩行,第一行為圍欄最短的長度,第二行為長度最短的前提下,最小的面積。
?
【數據范圍】
對于100%的數據4≤n≤100000,坐標的絕對值不超過109 。
?
-
題解
- 可能和凸包沒有什么關系吧。。。。。
- 周長顯然,直接將所有框起來即可,$2 * (max \{ x_{i} \} ?- ?min\{ x_{i} \} \ \ ?+ \ \ ?max \{ y_{i} \} ?- ?min\{ y_{i} \}) $
- 將所有都框起來并不是面積最小,因為有些部分收進去周長不會邊長,但是面積會減小;
- 但是也不能全部收進去因為會有類似于“凹”字的形狀收進去后周長會變大;
- 考慮每次從上到下掃描,維護當前橫坐標的最大值和最小值,如果更新了最大值或最小值就新建一個拐點和新點;
- 再從下面來一次,直接得到了點數O(2*n)的框,求面積即可;
1 #include<bits/stdc++.h>
2 #define inf 0x7fffffff
3 #define ll long long
4 using namespace std;
5 const int N =
200010;
6 int n,c1,c2,c3,c4;
7 struct P{
8 int x,y;
9 P(
int X=
0,
int Y=
0):x(X),y(Y){};
10 bool operator <(
const P&a)
const{
return x<
a.x;}
11 }p[N],p1[N],p2[N],p3[N],p4[N];
12 char gc(){
13 static char*P1,*P2,s[
1000000];
14 if(P1==P2)P2=(P1=s)+fread(s,
1,
1000000,stdin);
15 return(P1==P2)?EOF:*P1++
;
16 }
17 int rd(){
18 int x=
0,f=
1;
char c=
gc();
19 while(c<
'0'||c>
'9'){
if(c==
'-')f=-
1;c=
gc();}
20 while(c>=
'0'&&c<=
'9')x=x*
10+c-
'0',c=
gc();
21 return x*
f;
22 }
23 ll crs(
const P&a,
const P&b){
return (ll)a.x*b.y-(ll)a.y*
b.x;}
24 int main(){
25 #ifndef ONLINE_JUDGE
26 freopen(
"bzoj2146.in",
"r",stdin);
27 freopen(
"bzoj2146.out",
"w",stdout);
28 #endif
29 n=
rd();
30 for(
int i=
1;i<=n;++i)p[i].x=rd(),p[i].y=
rd();
31 sort(p+
1,p+n+
1);
32 for(
int i=
1,j=
1,mn=inf,mx=-inf;i<=n;i=
j){
33 int mn1=inf,mx1=-
inf;
34 for(;j<=n&&p[j].x==p[i].x;j++
){
35 mn1=
min(mn1,p[j].y);
36 mx1=
max(mx1,p[j].y);
37 }
38 if(mn1<
mn){
39 if(mn!=inf)p1[++c1]=
P(p[i].x,mn);
40 p1[++c1]=P(p[i].x,mn=
mn1);
41 }
42 if(mx1>
mx){
43 if(mx!=-inf)p2[++c2]=
P(p[i].x,mx);
44 p2[++c2]=P(p[i].x,mx=
mx1);
45 }
46 }
47
48 for(
int i=n,j=n,mn=inf,mx=-inf;i;i=
j){
49 int mn1=inf,mx1=-
inf;
50 for(;j&&p[j].x==p[i].x;j--
){
51 mn1=
min(mn1,p[j].y);
52 mx1=
max(mx1,p[j].y);
53 }
54 if(mn1<
mn){
55 if(mn!=inf)p3[++c3]=
P(p[i].x,mn);
56 p3[++c3]=P(p[i].x,mn=
mn1);
57 }
58 if(mx1>
mx){
59 if(mx!=-inf)p4[++c4]=
P(p[i].x,mx);
60 p4[++c4]=P(p[i].x,mx=
mx1);
61 }
62 }
63 P lst = p2[
1];
64 ll ans1=
0,ans2=
0;
65 for(
int i=
1;i<=c1;++
i){
66 ans1+=abs(p1[i].x-lst.x)+abs(p1[i].y-
lst.y);
67 ans2+=
crs(lst,p1[i]);
68 lst=
p1[i];
69 }
70 for(
int i=c3;i;--
i){
71 ans1+=abs(p3[i].x-lst.x)+abs(p3[i].y-
lst.y);
72 ans2+=
crs(lst,p3[i]);
73 lst=
p3[i];
74 }
75 for(
int i=
1;i<=c4;++
i){
76 ans1+=abs(p4[i].x-lst.x)+abs(p4[i].y-
lst.y);
77 ans2+=
crs(lst,p4[i]);
78 lst=
p4[i];
79 }
80 for(
int i=c2;i;--
i){
81 ans1+=abs(p2[i].x-lst.x)+abs(p2[i].y-
lst.y);
82 ans2+=
crs(lst,p2[i]);
83 lst=
p2[i];
84 }
85 printf(
"%lld\n%lld\n",ans1,ans2>>
1);
86 return 0;
87 }
bzoj2146 ?
轉載于:https://www.cnblogs.com/Paul-Guderian/p/10280320.html
總結
以上是生活随笔為你收集整理的bzoj2146 Construct的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。