http://acm.pku.edu.cn/JudgeOnline/problem?id=1113
Задача: Стена
Жил-был жадный Король. Он приказал своему главному Архитектору построить стену вокруг его замка. Король был таким жадным, что не послушал предложение Архитектора построить красивую кирпичную стену совершенной формы с изящными высокими башнями. Вместо этого он приказал построить стену вокруг всего замка, используя минимально количество камня, но потребовал, чтобы стена не подходила к замку ближе некоторого расстояния. Если Король узнает, что Архитектор использовал больше ресурсов для постройки стены, чем было абсолютно необходимо для удовлетворения требований, Архитектор лишится головы. Более того, Архитектор должен представить проект стены, где указано точное количество ресурсов.
Ваша задача - помочь бедному Архитектору сохранить голову, написав программу, определяющую минимальную длину стены, которую можно построить вокруг замка, удовлетворив требования Короля.
Задача слегка упрощается тем, что замок Короля представляет собой многоугольник и расположен на плоской поверхности. Архитектор уже сопоставил замку прямоугольную декартову систему координат т точно определил координаты каждого угла замка в футах.
Технические условия: Первая строка входных данных содержит два целых числа N и L, разделенных пробелом: N - число углов замке Короля, а L - минимальное число футов, на которое Король разрешил приблизить стену к замку.
Следующие N строк описывают координаты углов замка в порядке обхода по часовой стрелке. Каждая строка содержит два целых числа Xi и Yi, разделенных пробелом и предоставляющих собой координаты i-го угла в футах. Все углы имеют различные координаты и стены замка не пересекаются иначе как в углах.
(3 <= N <= 1000, 1 <= L <= 1000, -10000 <= Xi, Yi <= 10000)
Вывести единственное число - минимальную длину стены в футах, которая может быь построена вокруг замка согласно требований Короля. Представить Королю длину стены нужно в виде целого числа футов, потому что вещественные числа еще не изобретены. Однако результат нужно округлить так, чтобы он отличался не более чем на 8 дюймов от правильного (1 фут = 12 дюймов), потому что большей неточности Король не потерпит.
Это задача на нахождение длины обычной выпуклой оболочки. Требование, чтобы стена отстояла от стен замка как минимум на L футов, отражается только на длине кривых в углах. А длины этих кривых в сумме дают длину окружности радиусом L.
#include <stdio.h> #include <math.h> #include <string.h> #define N 1001 #define PI 3.14159265 typedef struct point{ int x,y; }point; point a[N]; int s[N],top; int n,l; int cross(point p0,point p1,point p2) { int x1=p1.x-p0.x, y1=p1.y-p0.y, x2=p2.x-p0.x, y2=p2.y-p0.y; return (x1*y2-x2*y1); } double distance(point p1,point p2) { return sqrt((double) ((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)) ); } int get_min() { int i,index; index=1; for(i=2;i<=n;i++) if(a[i].x<a[index].x || a[i].x==a[index].x&&a[i].y<a[index].y) index=i; return index; } void get_c() { int temp,t,pp,i; s[0]=get_min(); top=0; pp=s[top]; do{ t=pp+1; if(t>n) t=t-n+1; for(i=1;i<=n;i++) if(i!=pp) if( (temp=cross(a[pp],a[t],a[i]))>0 || temp==0 && distance(a[pp],a[i])>distance(a[pp],a[t]) ) t=i; s[++top]=t,pp=s[top]; }while(pp!=s[0]); } int main() { int i; double sum; while(scanf("%d%d",&n,&l)==2){ sum=0; for(i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y); get_c(); for(i=0;i<top;i++) sum+=distance(a[s[i]],a[s[i+1]]); sum+=2*PI*l; printf("%.0f\n",sum); } return 0; }