题目大意:
小Z接到命令去跟踪一个嫌疑犯。他一路跟踪走进一家商场,忽然那个人不见了。就在他焦急万分之际,耳机里响起了指挥部长官的声音:小Z听着,据我们监视,在你周围的人中,嫌疑犯距你第k远,请快速确认目标,实施抓捕!
给出小Z的当前置和周围所有人的位置,请你帮助小Z确认哪些人可能是嫌疑犯。
注意:嫌疑犯可能有多个!
思路:
这道题有点暴力模拟的成分。我们先用勾股定理求出每个人与小Z的距离,然后快排,最后再找出答案。
勾股定理详情见我博客 剑鱼行动
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int x,y,n,m,xx,yy,sum,k,a[30001],b[30001],i,j;
double f[30002];
char c;
void sorts(int l,int r) //快排代码
{
int i,j;
double t,z;
i=l;
j=r;
z=f[(i+j)/2];
do
{
while (f[i]<z) i++;
while (f[j]>z) j--;
if (i<=j)
{
t=f[i]; f[i]=f[j]; f[j]=t;
swap(a[i],a[j]);
swap(b[i],b[j]);
i++; j--;
}
}
while (i<j);
if (i<r) sorts(i,r);
if (j>l) sorts(l,j);
}
void sortt(int l,int r) //也是快排代码
{
int i,j,z;
double t;
i=l;
j=r;
z=(i+j)/2;
do
{
while (a[i]<a[z]||(a[i]==a[z]&&b[i]<b[z])) i++;
while (a[j]>a[z]||(a[j]==a[z]&&b[j]>b[z])) j--;
if (i<=j)
{
swap(a[i],a[j]);
swap(b[i],b[j]);
i++; j--;
}
}
while (i<=j);
if (i<r) sortt(i,r);
if (j>l) sortt(l,j);
}
int main()
{
freopen("suspect.in","r",stdin);
freopen("suspect.out","w",stdout);
f[30001]=2147483646;
scanf("%d%d%d%d",&x,&y,&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
f[i]=sqrt((x-a[i])*(x-a[i])+(y-b[i])*(y-b[i])); //勾股定理计算距离
}
sorts(1,n); //快排
sum=0;
for (i=n;i>=1;i--) //寻找距离小Z第k远的人
{
if (f[i]!=f[i+1]) sum++;
if (sum==m) break;
}
j=i-1;
sum=1;
while (f[j]==f[i]) //记录有多少个距离他第k远的人
{
j--;
sum++;
}
j++;
printf("%d\n",sum);
sortt(j,i); //快排
for (int q=j;q<=i;q++)
printf("%d %d\n",a[q],b[q]);
scanf("%c",&c);
return 0;
}