booj 1350 【POJ1113】墙

Description

一个贪婪的国王要求他的建筑师建一堵墙(图中虚线)围绕他的城堡(图中实线),且墙与城堡之间的距离总不小于一个数L。输入城堡各个节点(图中实线与实线的交点)的坐标和L,要求最小的墙壁周长。

Input

输入文件第一行N(3 <= N <= 1000)和L(1 <= L <= 1000),其中N为节点个数。
以下N行每行是各个节点的横坐标Xi和纵坐标Yi,其中-10000 <= Xi,Yi <= 10000。

Output

输出文件仅一个数,为最小的墙壁周长(四舍五入至整数)。

Sample Input

9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output

1628

初中题吧,太水了:
。。但是我还是被卡精度了。
还有四舍五入!!!
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct Vector{
 	double x,y;
    Vector operator +(Vector &a){
    	Vector v1;
    	v1.x=this->x+a.x,v1.y=this->y+a.y;
    	return v1;
		};
    Vector operator -(Vector &a){
   	 	Vector v1;
    	v1.x=this->x- a.x,v1.y=this->y -a.y;
	    return v1;
		};
    double operator * (Vector &a){
	    return ((this->x)*a.y)-(a.x*(this->y));
		};
}P[200055] ; 
bool cmp(Vector a,Vector b){
	return (a.y<b.y)||((a.y==b.y)&&(a.x<b.x));
}
double Get_Long(Vector a,Vector b){
	return sqrt(fabs(a.x-b.x)*fabs(a.x-b.x)+fabs(a.y-b.y)*fabs(a.y-b.y));
}
bool vis[10005];
int ch[10005];
int top=0;
int n;
double L;
bool judge(int a,int b,int c){
	Vector q=P[c]-P[a];
	Vector w=P[b]-P[a];
	if(q*w>=0)return 1;
	else return 0;
}
void TUBao(){
	sort(P+1,P+n+1,cmp);
	ch[++top]=1;
	int k=2;
	while(k<=n){
		while(top>1&&judge(ch[top-1],ch[top],k))vis[ch[top--]]=0;
		ch[++top]=k;
		vis[k]=1;
		k++;
	}
	int Max=top;
	k=n-1;
	while(k>=1){
		while(vis[k])k--;
		while(top>Max&&judge(ch[top-1],ch[top],k))vis[ch[top--]]=0;
		ch[++top]=k;
		vis[k]=1;
		k--;
	}
}
int main(){
	
	scanf("%d%lf",&n,&L);
	for(int i=1;i<=n;i++){
		scanf("%lf%lf",&P[i].x,&P[i].y);
	}
	TUBao();
	double C=0.0;
	for(int i=2;i<=top;i++){
		C+=Get_Long(P[ch[i-1]],P[ch[i]]);
	}
	printf("%.0lf",(C+2*3.141592653589793*L));
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值