这道题和NYOJ上的http://acm.nyist.net/JudgeOnline/problem.php?pid=7非常像,都是找中位数的题目。具体这道题来说,在满足条件的前提下,不断的删除点,由于数据比较小,所以可以直接循环,每次循环的时候删除一个点,若有多个点满足删除的条件,则找最省钱的那个删除即可。
题目地址:http://acm.uestc.edu.cn/problem.php?pid=1650
ac代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1010;
int num[N],px[N],py[N],visted[N];
struct point
{
int x,y;
}pp[N];
int main()
{
int numcase,n,m;
scanf("%d",&numcase);
for(int k = 1;k <= numcase;++k)
{
scanf("%d%d",&n,&m);
int sum = 0;
for(int i = 1;i <= n;++i)
{
scanf("%d",&num[i]);
}
for(int i = 1;i <= n;++i)
{
scanf("%d%d",&pp[i].x,&pp[i].y);
}
bool flag = true;
memset(visted,0,sizeof(visted));
while(m && flag)
{
flag = false;
int numpoint = 0;
for(int i = 1;i <= n;++i)
{
if(!visted[i])
{
px[numpoint] = pp[i].x;
py[numpoint++] = pp[i].y;
}
}
sort(px,px+numpoint);
sort(py,py+numpoint);
int midx = px[(numpoint-1)/2];
int midy = py[(numpoint-1)/2];
//printf("midx= %d midy=%d\n",midx,midy);
int pos = 0,mm = 0;
for(int i = 1;i <= n;++i)
{
int y = abs(midx - pp[i].x) + abs(midy - pp[i].y);
if(!visted[i])
{
if(num[i] <= y)
{
flag = true;
if(y - num[i] > mm)
{
mm = y -num[i];
pos = i;
}
}
}
}
if(flag)
{
visted[pos] = 1;
m--;
sum += num[pos];
// printf("pos=%d\n",pos);
}
}
int numpoint = 0;
for(int i = 1;i <= n;++i)
{
if(!visted[i])
{
px[numpoint] = pp[i].x;
py[numpoint++] = pp[i].y;
}
}
sort(px,px+numpoint);
sort(py,py+numpoint);
int midx = px[(numpoint-1)/2];
int midy = py[(numpoint-1)/2];
for(int i = 1;i <= n;++i)
{
if(!visted[i])
{
int y = abs(midx - pp[i].x) + abs(midy - pp[i].y);
sum += y;
}
}
printf("Case #%d: %d\n",k,sum);
}
return 0;
}