POJ3996 Air Strike

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。

但是有朋友过来,早上下午都有,所以计划都打乱了。

早上做了两道,下午做了两道,晚上再补上一道,十道题算是做了一半吧。

虽然最近状态不是很好,脑里想的东西也是很多,但是还是要静下心来一件一件地做好。

嗯,看到大家都在刷题,加油吧!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值