传送门:
POJ:点击打开链接
HDU:点击打开链接
下面是POJ上的题;
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 29121 | Accepted: 9746 |
Description
Input
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
Hint
题意大致就是要你求将所有点包起来的那个面的最小周长, 以及还有一个以L为半径圆的周长。。
用的是Andrew算法
</pre><pre name="code" class="cpp"> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<sstream> #include<cmath> using namespace std; #define f1(i, n) for(int i=0; i<n; i++) #define f2(i, m) for(int i=1; i<=m; i++) #define f3(i, n) for(int i=n; i>=0; i--) #define M 1005 #define PI 3.1415926 struct Point { double x, y; }; void sort(Point *p, int n) //按照x从小到大排序(如果x相同, 按照y从小到大排序) { Point temp; f1(i, n-1) f1(j, n-i-1) { if( (p[j].x > p[j+1].x) || (p[j].x==p[j+1].x && p[j].y>p[j+1].y) ) { temp = p[j]; p[j] = p[j+1]; p[j+1] = temp; } } } int cross(int x1, int y1, int x2, int y2) //看P[i]是否是在其内部。。</span></span> { if(x1*y2-x2*y1<=0) //叉积小于0,说明p[i]在当前前进方向的右边,因此需要从凸包中删除c[m-1],c[m-2]</span><span> return 0; else return 1; } double dis(Point a, Point b)//求两个凸包点之间的长度。。</span><span> { return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ); } int convexhull(Point *p, Point *c, int n) { int m = 0; f1(i, n)//下凸包</span><span> { while( m>1 && !cross(c[m-2].x-c[m-1].x, c[m-2].y-c[m-1].y, c[m-2].x-p[i].x, c[m-2].y-p[i].y) ) m--; c[m++] = p[i]; } int k = m; f3(i, n-2)//求上凸包</span><span> { while( m>k && !cross(c[m-2].x-c[m-1].x, c[m-2].y-c[m-1].y, c[m-2].x-p[i].x, c[m-2].y-p[i].y) ) m--; c[m++] = p[i]; } if(n>1) m--; return m; } int main() { Point a[M], p[M]; double sum; int n, r; while( cin>>n>>r ) { sum=0.0; f1(i, n) scanf("%lf %lf", &a[i].x, &a[i].y); sort (a, n); int m = convexhull(a, p, n); f2(i, m) sum+=dis( p[i], p[i-1] ); sum+=2*PI*r; printf("%.lf\n", sum); } return 0; }
下面是HDU上AC的代码。。之所以贴出来, 是因为PE过一次。。要注意一下格式。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<sstream> #include<cmath> using namespace std; #define f1(i, n) for(int i=0; i<n; i++) #define f2(i, m) for(int i=1; i<=m; i++) #define f3(i, n) for(int i=n; i>=0; i--) #define M 1005 #define PI 3.1415926 struct Point { double x, y; }; void sort(Point *p, int n) { Point temp; f1(i, n-1) f1(j, n-i-1) { if( (p[j].x > p[j+1].x) || (p[j].x==p[j+1].x && p[j].y>p[j+1].y) ) { temp = p[j]; p[j] = p[j+1]; p[j+1] = temp; } } } int cross(int x1, int y1, int x2, int y2) { if(x1*y2-x2*y1<=0) return 0; else return 1; } double dis(Point a, Point b) { return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ); } int convexhull(Point *p, Point *c, int n) { int m = 0; f1(i, n) { while( m>1 && !cross(c[m-2].x-c[m-1].x, c[m-2].y-c[m-1].y, c[m-2].x-p[i].x, c[m-2].y-p[i].y) ) m--; c[m++] = p[i]; } int k = m; f3(i, n-2) { while( m>k && !cross(c[m-2].x-c[m-1].x, c[m-2].y-c[m-1].y, c[m-2].x-p[i].x, c[m-2].y-p[i].y) ) m--; c[m++] = p[i]; } if(n>1) m--; return m; } int main() { Point a[M], p[M]; double sum; int t; while( cin>>t ) { while( t-- ) { sum=0.0; int n, r; cin>>n>>r; f1(i, n) scanf("%lf %lf", &a[i].x, &a[i].y); sort (a, n); int m = convexhull(a, p, n); f2(i, m) sum+=dis( p[i], p[i-1] ); sum+=2*PI*r; printf("%.lf\n", sum); if(t) printf("\n"); } } return 0; }
POJ 1113 || HDU 1348: wall(凸包问题),布布扣,bubuko.com
POJ 1113 || HDU 1348: wall(凸包问题)
原文:http://blog.csdn.net/u013487051/article/details/37736951