六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 27|回复: 0

【凸包Graham_Scan算法】HDU 1348 Wall

[复制链接]

升级  68.4%

272

主题

272

主题

272

主题

进士

Rank: 4

积分
842
 楼主| 发表于 2013-1-26 12:35:41 | 显示全部楼层 |阅读模式
http://acm.hdu.edu.cn/showproblem.php?pid=1348

典型凸包题,求外围城墙的周长
Sample Input
1
9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output
1628


#include <iostream>#include <fstream>#include <algorithm>#include <string>#include <set>//#include <map>#include <queue>#include <utility>#include <stack>#include <list>#include <vector>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <ctype.h>using namespace std;#define PI 3.14159265struct point{double x, y, angel;}p[1005], ch[1005];double dist (point a, point b){return sqrt ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}double multi (point a, point b, point c){double x1, y1, x2, y2;x1 = b.x - a.x;y1 = b.y - a.y;x2 = c.x - b.x;y2 = c.y - b.y;return x1*y2 - x2*y1;}bool cmp (point a, point b){if (a.y == b.y)return a.x < b.x;return a.y < b.y;}bool cmp2 (point a, point b){if (a.angel == b.angel){if (a.x == b.x)return a.y > b.y;return a.x > b.x;}return a.angel < b.angel;}int main(){int n, i, top, t;double r, len;scanf ("%d", &t);while (t--){scanf ("%d%lf", &n, &r);for (i = 0; i < n; i++)scanf ("%lf%lf", &p.x, &p.y);sort (p, p+n, cmp);    //找到左下角的p[0]//找相对于p[0]的极角,并把除了p[0]以外的点按照极角排序for (i = 1; i < n; i++)p.angel = atan2 (p.y-p[0].y, p.x-p[0].x);sort (p+1, p+n, cmp2);//Graham_Scan算法ch[0] = p[0], ch[1] = p[1], ch[2] = p[2];top = 3;for (i = 3; i < n; i++){while (top > 2 && multi (ch[top-2], ch[top-1], p) <= 0)top--;ch[top++] = p;}//求周长len = dist (ch[0], ch[top-1]);for (i = 1; i < top; i++)len += dist (ch, ch[i-1]);len += 2 * PI * r;    //加上圆弧,刚好为一个圆!printf ("%.0lf\n", len);if (t)printf ("\n");}return 0;}
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表