题意:有两个中心点A,B,有其他n个点,每个点到中心点都有以它们的距离为半径的圆的辐射范围,求最小的辐射范围半径能覆盖所有的点。
分析:这题纯靠想解题方法。一开始方向走错了一直WA。开始的想法:每输入一个点就计算它到A,B的距离,只取较小值,不断更新结果。WA的过程中才慢慢发现这样做会有很多特殊情况,但当时都没想过要换思路,只是不断地增加代码讨论情况,下次一定记得发现方法有很多不足就转换思路。正确做法:每输入一个点只计算它到A点的距离,从大到小排序,遍历依次判断加入把这一点归到B的覆盖范围是否结果会更小,不断更新答案。后来又WA了几遍,原因:中间当判断出一个点若归为B的范围时不能更新答案就break退出循环,这是错误的,应该要遍历完。
代码:
#include<iostream> #include<algorithm> using namespace std; struct h{ long long x,y; long long dis; }a[100008]; long long dd,dis,tmp; bool cmp(h a,h b) { return a.dis>b.dis; } int main() { int t,n,x2,x3,y2,y3,x,y; cin>>t; while(t--){ cin>>x2>>y2>>x3>>y3; cin>>n; for(int i=0;i<n;i++){ cin>>x>>y; a[i].x=x,a[i].y=y; a[i].dis=(x-x2)*(x-x2)+(y-y2)*(y-y2); } sort(a,a+n,cmp); a[n].dis=0; dd=a[0].dis,dis=0; for(int i=0;i<n;i++){ tmp=(a[i].x-x3)*(a[i].x-x3)+(a[i].y-y3)*(a[i].y-y3); if(dis<tmp) dis=tmp; if(dis+a[i+1].dis<=dd) dd=dis+a[i+1].dis; // else break;思路对了以后还是WA的原因 } cout<<dd<<endl; } }
时间: 2024-10-29 19:09:56