2 条题解

  • 2
    @ 2023-10-4 8:33:10

    声明:本题洛谷有原题,想C的去C题解。怕你们说题解代码和我一样

    课外知识:勾股定理 d2=(x1x2)2+(y1y2)2d^2=(x_1-x_2)^2+(y_1-y_2)^2

    这道题首先要明确所有导弹不是被11号系统拦截就是被22号系统拦截

    我们看到这道题的数据范围是101055次方,大概是nlognnlog_n复杂度,联想到sortsort排序

    让我们思考一下最优解,在最优解中11号系统肯定先拦下距离自己近的

    如果11号去拦距离它远的导弹的话,其实就捎带脚的把近的导弹拦截了

    如果我们把所有导弹按照对11号的距离进行升序排序,通过刚才的思考我们知道肯定是11号拦截一个前缀,剩下的后缀交给22

    那么我们枚举一下这个前缀和后缀的分界点即可(分界点我们此处定义为前缀的最后一个点)

    前缀处理的11号系统代价比较好算,就是分界点到11号系统的距离

    22号系统此时就不能再排序看后缀谁是最大的来计算代价,此时需要我们预处理出来一个数组,让di=d_i= 包括第i以及它后面的导弹中最远距离

    • 0
      @ 2025-7-4 14:07:43

      预处理枚举情况的导弹拦截系统工作半径 对答案取最小值即可

      #include<bits/stdc++.h>
      using namespace std;
      int nx,ny,mx,my;
      int n;
      struct node{
      	int x,y,dx,dy;
      }a[100005];
      int dx[100005],dy[100005];
      bool cmp(node i,node j){
      	return i.dx<j.dx;
      }
      int ans=1e9;
      int jl(int aa,int b,int c,int d){
      	return (aa-c)*(aa-c)+(b-d)*(b-d);
      }
      signed main(){
      	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
      	cin>>nx>>ny>>mx>>my;
      	cin>>n;
      	for(int i=1;i<=n;i++){
      		cin>>a[i].x>>a[i].y;
      		a[i].dx=jl(a[i].x,a[i].y,nx,ny);
      		a[i].dy=jl(a[i].x,a[i].y,mx,my);
      //提前算出代价
      	}
      	sort(a+1,a+n+1,cmp);
      	for(int i=1;i<=n;i++){
      		dx[i]=max(dx[i-1],a[i].dx);
      	}
      	for(int i=n;i>=1;i--){
      		dy[i]=max(dy[i+1],a[i].dy);
      	}//根据题意预处理
      	for(int i=0;i<=n;i++){
      //注意要从 0 开始,因为导弹拦截系统可以不拦截导弹
      		ans=min(ans,dx[i]+dy[i+1]);
      	}
      	cout<<ans;
      	return 0;
      }
      
      • 1

      信息

      ID
      226
      时间
      1000ms
      内存
      256MiB
      难度
      5
      标签
      (无)
      递交数
      234
      已通过
      93
      上传者