ICPC2021上海热身Two Point Removal
今天ICPC上海热身赛,本来我是负责计算几何的
但我队伍做题把A分为两种情况
1.删去两个相邻的点使得线段最短
2.删去两个不相邻的点使得线段最短
第二种如何找出不相邻的两个点的时候,把n*n优化想不出,后面学长来写了,但写的时候我提起昨天CF的B题(模拟)结构体排序,保存排序前的下标,有了这一思路,只需要取排序后的四个,判断4个判断是不是相邻和可以使线段减少最多即可
最终顺利签了到
这是赛后我的个人代码
1 #include2 #include 3 #include 4 #define x first 5 #define y second 6 using namespace std; 7 typedef pair<double,double> PDD; 8 9 PDD operator - (const PDD& A,const PDD& B) 10 { 11 return PDD(A.x-B.x,A.y-B.y); 12 } 13 double get_dist(PDD A) 14 { 15 return sqrt(A.x*A.x+A.y*A.y); 16 } 17 struct node 18 { 19 double ss; 20 int shenfen; 21 }b[100010]; 22 23 bool cmp1(node c,node d) 24 { 25 return c.ss>d.ss; 26 } 27 28 PDD a[100010]; 29 int main() 30 { 31 int n; 32 cin>>n; 33 for(int i=1;i<=n;i++) 34 { 35 double sy; 36 cin>>sy; 37 a[i]={double(i),sy}; 38 } 39 a[0]={0.0,0.0},a[n+1]={(double)n+1.0,0.0}; 40 41 double s1=0,s2=0; 42 for(int i=1;i<=n+1;i++) 43 { 44 s1+=get_dist(a[i]-a[i-1]); 45 } 46 s2=s1; 47 for(int i=1;i<=n;i++) 48 { 49 b[i].ss=get_dist(a[i]-a[i-1])+get_dist(a[i+1]-a[i])-get_dist(a[i+1]-a[i-1]); 50 b[i].shenfen=i; 51 } 52 sort(b+1,b+1+n,cmp1); 53 54 double max1=0.0; 55 for(int i=1;n>=3&&i<=4&&i<=n;i++) 56 { 57 if(b[i].ss+b[i+1].ss>max1&&abs(b[i].shenfen-b[i+1].shenfen)>1) 58 { 59 max1=b[i].ss+b[i+1].ss; 60 } 61 } 62 s1-=max1; 63 64 65 double max_two=-1e4; 66 for(int i=1;i<=n-1;i++) 67 { 68 if(get_dist(a[i]-a[i-1])+get_dist(a[i+1]-a[i])+get_dist(a[i+2]-a[i+1])-get_dist(a[i+2]-a[i-1])>=max_two) 69 { 70 max_two=get_dist(a[i]-a[i-1]) + get_dist(a[i+1]-a[i]) + get_dist(a[i+2]-a[i+1])-get_dist(a[i+2]-a[i-1]); 71 72 } 73 } 74 s2-=max_two; 75 76 if(s1-s2>1e-8) 77 { 78 printf("%.8lf\n",s2); 79 } 80 else 81 { 82 printf("%.8lf\n",s1); 83 } 84 85 return 0; 86 87 }