如题= =自用模板

用的扫描法 poj上jdk太老了只能用第二份模板 要注意特判1个点和两个点的情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
FastScanner sc=new FastScanner();
PrintWriter pw=new PrintWriter(System.out);
ConvexHull ch=new ConvexHull();
double PI=Math.acos(-1);
while(sc.hasNext()){
int n=sc.nextInt();
int l=sc.nextInt();
Point[]p=new Point[n];
for(int i=0;i<n;i++){
int x=sc.nextInt();
int y=sc.nextInt();
p[i]=new Point(x,y);
}
if(n==1){
pw.println(0);
}else if(n==2){
pw.println(Math.round(ch.dis(p[0], p[1])+Math.acos(-1)*l*2));
}else{
ch.initsort(p);
ch.graham(p);
double sum=0;
for(int i=0;i<=ch.top;i++){
sum+=ch.dis(p[ch.stack[i]],p[ch.stack[(i+1)%(ch.top+1)]]);
}
sum+=PI*l*2;
pw.println(Math.round(sum));
}
pw.flush();
}

}

}
/*stack存凸包上的点 从0~top 用之前先将所有点基于左下的点极角排序*/
class ConvexHull{
double eps=1e-9;
int maxn=10000;
int[]stack;
int top;
ConvexHull(){
stack=new int[maxn];
}
double cross(Point p0,Point p1,Point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
double dis(Point p1,Point p2){
return Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}
void initsort(Point []convex){
Point p0=new Point(convex[0]);
int k=0;
for(int i=1;i<convex.length;i++){
if((p0.y>convex[i].y) || ((p0.y==convex[i].y)&&(p0.x>convex[i].x)) ){
p0.x=convex[i].x;
p0.y=convex[i].y;
k=i;
}
}
convex[k]=convex[0];
convex[0]=p0;
Point z=convex[0];
Arrays.sort(convex,1,convex.length,new Comparator<Point>(){
public int compare(Point a, Point b) {
double tmp=cross(z,a,b);
if(tmp>0) return -1;
else if(Math.abs(tmp-0)<eps&&dis(z,a)<dis(z,b)) return -1;
else if(Math.abs(tmp-0)<eps&&Math.abs(dis(z,a)-dis(z,b))<eps) return 0;
else return 1;
}

});
}
void graham(Point []convex){
int i;
int n=convex.length;
if(n==1){
top=0;
stack[0]=0;
}
if(n==2){
top=1;
stack[0]=0;
stack[1]=1;
}
if(n>2){
for(i=0;i<=1;i++){
stack[i]=i;
}
top=1;
for(i=2;i<n;i++){
while(top>0&&(cross(convex[stack[top-1]],convex[stack[top]],convex[i])<0||(Math.abs(cross(convex[stack[top-1]],convex[stack[top]],convex[i]))<eps))) top--;
top++;
stack[top]=i;
}
}
}
}
class Point{
double x;
double y;
static Point k;
static double eps=1e-9;
Point(double x,double y){
this.x=x;
this.y=y;
}
Point(Point p){
this.x=p.x;
this.y=p.y;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
FastScanner sc=new FastScanner();
PrintWriter pw=new PrintWriter(System.out);
ConvexHull ch=new ConvexHull();
double PI=Math.acos(-1);
while(sc.hasNext()){
int n=sc.nextInt();
int l=sc.nextInt();
Point[]p=new Point[n];
for(int i=0;i<n;i++){
int x=sc.nextInt();
int y=sc.nextInt();
p[i]=new Point(x,y);
}
if(n==1){
pw.println(0);
}else if(n==2){
pw.println(Math.round(ch.dis(p[0], p[1])+Math.acos(-1)*l*2));
}else{
ch.initsort(p);
ch.graham(p);
double sum=0;
for(int i=0;i<=ch.top;i++){
sum+=ch.dis(p[ch.stack[i]],p[ch.stack[(i+1)%(ch.top+1)]]);
}
sum+=PI*l*2;
pw.println(Math.round(sum));
}
pw.flush();
}

}

}
class Point implements Comparable<Point>{
double x;
double y;
static Point k;
static double eps=1e-9;
Point(double x,double y){
this.x=x;
this.y=y;
}
Point(Point p){
this.x=p.x;
this.y=p.y;
}
@Override
public int compareTo(Point b) {
double tmp=cross(k,this,b);
if(tmp>0) return -1;
else if(Math.abs(tmp-0)<eps&&dis(k,this)<dis(k,b)) return -1;
else if(Math.abs(tmp-0)<eps&&Math.abs(dis(k,this)-dis(k,b))<eps) return 0;
else return 1;
}
double cross(Point p0,Point p1,Point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
double dis(Point p1,Point p2){
return Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}
}
class ConvexHull{
double eps=1e-9;
int maxn=10000;
int[]stack;
int top;
ConvexHull(){
stack=new int[maxn];
}
double cross(Point p0,Point p1,Point p2){
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
double dis(Point p1,Point p2){
return Math.sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}
void initsort(Point []convex){
Point p0=new Point(convex[0]);
int k=0;
for(int i=1;i<convex.length;i++){
if((p0.y>convex[i].y) || ((p0.y==convex[i].y)&&(p0.x>convex[i].x)) ){
p0.x=convex[i].x;
p0.y=convex[i].y;
k=i;
}
}
convex[k]=convex[0];
convex[0]=p0;
Point.k=convex[0];
Arrays.sort(convex,1,convex.length);
}
void graham(Point []convex){
int i;
int n=convex.length;
if(n==1){
top=0;
stack[0]=0;
}
if(n==2){
top=1;
stack[0]=0;
stack[1]=1;
}
if(n>2){
for(i=0;i<=1;i++)
stack[i]=i;
top=1;
for(i=2;i<n;i++) {
while(top>0&&(cross(convex[stack[top-1]],convex[stack[top]],convex[i])<0||(Math.abs(cross(convex[stack[top-1]],convex[stack[top]],convex[i]))<eps))) top--;
top++;
stack[top]=i;
}
}
}
}