写了个模拟退火,自认为挺对,但是WA40,感觉是随机的时候正确性有点问题,但是不知道哪里不对……
#include<bits/stdc++.h>
using namespace std;
const double down=0.997;
int n,m,r;double lx,ly,nx,ny,x[1000001],y[1000001],len[1000001],xx[1000001],yy[1000001],mx,my,sx,sy;
int sqr(double ax,double ay){
double lenn=r;int ans=0;
for(int i=1;i<=n;i++)lenn=min(lenn,sqrt((ax-x[i])*(ax-x[i])+(ay-y[i])*(ay-y[i]))-len[i]);
for(int i=1;i<=m;i++)if(sqrt((ax-xx[i])*(ax-xx[i])+(ay-yy[i])*(ay-yy[i]))<=lenn)ans++;
return ans;
}
void sa(){
double t=10000;
while(t>1e-9){
double nx=lx+(rand()*2-RAND_MAX)*t,ny=ly+(rand()*2-RAND_MAX)*t;
while(fabs(nx)>mx)nx/=2;
while(fabs(ny)>my)ny/=2;
double dt=sqr(lx,ly)-sqr(nx,ny);
if(dt<0)lx=nx,ly=ny;
else if(exp(-dt/t)*RAND_MAX>rand())lx=nx,ly=ny;
t*=down;
}
}
int main(){
srand(time(0));
lx=ly=0;cin>>n>>m>>r;
for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&x[i],&y[i],&len[i]);
for(int i=1;i<=m;i++)scanf("%lf%lf",&xx[i],&yy[i]),mx=max(mx,fabs(xx[i])),my=max(my,fabs(yy[i])),sx+=xx[i],sy+=yy[i];
lx=sx/m,ly=sy/m;for(int i=1;i<=10;i++)sa();
printf("%d\n",sqr(lx,ly));
return 0;
}