Problem Address:http://poj.org/problem?id=3996
【前言】
一道不是很难的题。
但是不知道为什么会一直没有思路。
之前居然还想出了DP什么的。
后来发现其实很简单。
【思路】
先把所有missile放到第一个tower,并按与第一个tower的距离从小到大的顺序排列。
从后往前判断,如果当前第一个tower的面积小于规定面积,则可以进行以下计算,否则不能。计算完成后把这个missile放到第二个tower里。
该计算为:把放在第二个tower里的所有missile按与它的距离从小到大排列(在做上面的步骤的过程中该missile可以插入到第二个tower中维护),计算可用面积(等于总面积减去第一个tower的面积)所能容许的最多missile数。两个tower的个数相加(由于第一个tower已排列,所以可以简单得出其包含的missile数)与最大值total比较并更新。
直到最后第一个tower的最后一个missile计算完毕。
进行最后一轮的对第二个tower的计算。
输出结果。
【代码】
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
const double pi = 3.141;
struct node
{
double x;
double y;
double d1;
double d2;
bool operator < ( const node a) const
{
if (d1!=a.d1) return d1<a.d1;
else return d2<a.d2;
}
}missile[1005],a,b;
struct cmp
{
bool operator ()(const node &m1, const node &m2)
{
return m1.d2<m2.d2;
}
};
multiset<node, cmp> s;
multiset<node, cmp>::iterator it;
int main()
{
int n;
int i;
double area, left;
int total;
int ct;
int index = 1;
while(scanf("%d", &n)!=EOF)
{
if (n==0) break;
scanf("%lf %lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y, &area);
for (i=0; i<n; i++)
{
scanf("%lf %lf", &missile[i].x, &missile[i].y);
missile[i].d1 = ((missile[i].x-a.x)*(missile[i].x-a.x)+(missile[i].y-a.y)*(missile[i].y-a.y))*pi;
missile[i].d2 = ((missile[i].x-b.x)*(missile[i].x-b.x)+(missile[i].y-b.y)*(missile[i].y-b.y))*pi;
}
sort(missile, missile+n);
s.clear();
total = 0;
for (i=n-1; i>=0; i--)
{
if (missile[i].d1<=area)
{
left = area - missile[i].d1;
ct = 0;
for (it=s.begin(); it!=s.end(); it++)
{
if ((*it).d2>left) break;
ct++;
}
if (ct+i+1>total)
total = ct + i + 1;
}
s.insert(missile[i]);
}
ct = 0;
for (it=s.begin(); it!=s.end(); it++)
{
if ((*it).d2>area) break;
ct++;
}
if (ct>total)
total = ct;
printf("%d. %d\n", index, n-total);
index++;
}
return 0;
}
【P.S】
今天去poj上跟着做一个contest。
但是有朋友过来,早上下午都有,所以计划都打乱了。
早上做了两道,下午做了两道,晚上再补上一道,十道题算是做了一半吧。
虽然最近状态不是很好,脑里想的东西也是很多,但是还是要静下心来一件一件地做好。
嗯,看到大家都在刷题,加油吧!