1. 程式人生 > >汕頭市隊賽 SRM 06 C 秀恩愛

汕頭市隊賽 SRM 06 C 秀恩愛

none max ring 中心 輸入 getch 1.0 long 問題

C 秀恩愛 SRM 06

背景&&描述

KPM坐在直升機上俯瞰小漁村景象。 漁村可看作二維平面,密密麻麻地到處都是單身狗,KPM當前所在坐標為(sx,sy)。 KPM的後宮團們自發地聚集在一起為他送行,從空中看,後宮團形成了一個多邊形。 當然了KPM是不在那個多邊形內的。 直升機突然開始原地轉圈,後宮團們因為想看著KPM的正臉,所以也跟著以KPM所在坐標為中心旋轉。 後宮團所經之處單身狗屍橫遍野。趕來救治傷員的醫護人員想知道,多邊形掃過的面積是多少。 註意,本題不保證橫坐標互不相同、縱坐標互不相同什麽的。 請註意運算過程中可能出現的/0等問題。

輸入格式

第一行三個整數,n,sx,sy。n表示多邊形的頂點數。

接下來n行每行倆整數,分別表示多邊形一個頂點的橫縱坐標。

(頂點是按照順時針或者逆時針順序給出的,並且所有點的坐標絕對值<=技術分享,保證不存在共線的三個頂點)

輸出格式

一個整數,表示面積四舍五入為整數的結果。

樣例輸入

3 0 0
0 1
-1 2
1 2

樣例輸出

13

數據範圍與約定

  • 對於100%的數據:技術分享

樣例解釋

技術分享

這道題主要是求最小半徑以及最大半徑

易證明最大半徑mx一定在頂點位置

而最小半徑也可能在兩點的直線上

明白這一點後代碼就很好實現了 不過要註意精度問題 今天似乎大爺們都被精度卡了 2333

技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int M=155;
const double P=3.141592653589793238462643383279502884;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    
while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();} return ans*f; } double mx,mn=1e15; double k1,k2,b,L,mxx,mnx,nx; LL x[M],y[M],n,sx,sy; int main() { n=read(); sx=read(); sy=read(); for(int i=1;i<=n;i++){ x[i]=read()-sx; y[i]=read()-sy; L=1.0*(fabs(x[i])*fabs(x[i])+fabs(y[i])*fabs(y[i])); mx=max(mx,L); mn=min(mn,L); } for(int i=1;i<=n;i++){ int j=i+1<=n?i+1:1; if(x[i]==x[j]){ if((y[i]>0&&y[j]<0)||(y[i]<0&&y[j]>0)) mn=min(mn,(double)x[i]*x[j]); continue; } mxx=max(x[i],x[j]); mnx=min(x[i],x[j]); if(y[i]==y[j]){ if(mxx>0&&mnx<0) mn=min(mn,(double)y[i]*y[j]); continue; } k1=(double)(y[i]-y[j])/(x[i]-x[j]); b=(double) y[i]-k1*x[i]; k2=-1.0/k1; nx=b/(k2-k1); if(nx>mxx||nx<mnx) continue; L=b/sqrt(k1*k1+1); mn=min(mn,L*L); } printf("%lld",(long long)(P*(mx-mn)+0.5)); return 0; }
View Code

汕頭市隊賽 SRM 06 C 秀恩愛