洛谷P3428 AKC-Special Forces Manoeuvres

这篇博客讨论了一个军事演习问题,目标是确定最少需要派出多少士兵才能确保在最坏情况下至少有一人生还。士兵们以特定顺序空降,每个士兵有生存半径,如果炸弹在其范围内,士兵会引爆炸弹。通过计算和几何分析,可以找到最佳部署策略,以避免所有士兵牺牲。博客提供了一个C++实现的解决方案,该方案考虑了士兵之间的位置关系和炸弹可能的位置,以确保至少一名士兵能够幸存。
摘要由CSDN通过智能技术生成

 展开

题目描述

一个秘密组织正在沙漠中举行一次军事演习。本次演习的目标是拆除隐藏在沙漠中的一个炸弹。

演习的第一部分是空降作战。每个士兵按照一定的顺序从悬停在沙漠上空的直升机上跳下。着陆时,每个士兵都会停在他所在的着陆点。

每个空降兵都有一个生存半径。如果炸弹与他的距离小于或等于这个生存半径的话,空降兵便会牺牲自己引爆炸弹。指挥官希望能派出尽可能少的士兵,但他希望在最坏情况下至少有一个士兵能够生还。

整个沙漠可以抽象为一个平面,每个士兵的着陆点可以用一个坐标 (x,y)(x,y) 表示,他的生存半径我们设为 rr。所有士兵的信息按照他们跳伞时的顺序给出,即第 ii 个士兵跳伞时,前 i-1i−1 个士兵都已经着陆。

你的任务是:从标准输入读入所有士兵的信息,输出最少需要派出的士兵数量。

输入格式

第一行一个整数 nn。

接下来 nn 行,第 ii 行包含三个整数 x_i,y_i,r_ixi​,yi​,ri​,代表第 ii 个士兵的着陆坐标为 (x_i,y_i)(xi​,yi​),生存半径为 r_iri​。

输出格式

如果无法让至少一个士兵生还的话,输出 NIE

否则输出一个整数,代表至少需要派出的士兵数量。

输入输出样例

输入 #1复制

5
2 2 4
7 2 3
4 3 1
5 7 1
8 7 1

输出 #1复制

4

说明/提示

最坏情况下炸弹位于 (5,3)(5,3),前三个士兵都会被炸死,第四个士兵会生还。

上代码:
 

#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;

const double eps=1e-6;

inline int sgn(reg double x){
	if(fabs(x)<eps)
		return 0;
	else
		return x<0?-1:1;
}

inline double sqr(reg double x){
	return x*x;
}

const int MAXN=2e3+5;

struct Vector{
	double x,y;
	inline Vector(reg double x=0,reg double y=0):x(x),y(y){
		return;
	}
	inline Vector operator+(const Vector& a)const{
		return Vector(x+a.x,y+a.y);
	}
	inline Vector operator-(const Vector& a)const{
		return Vector(x-a.x,y-a.y);
	}
	inline Vector operator*(const double a)const{
		return Vector(x*a,y*a);
	}
};

inline double dot(const Vector& a,const Vector& b){
	return a.x*b.x+a.y*b.y;
}

inline double cross(const Vector& a,const Vector& b){
	return a.x*b.y-a.y*b.x;
}

typedef Vector Point;

inline double getDis2(const Point& a,const Point& b){
	return dot(a-b,a-b);
}

inline double getDis(const Point& a,const Point& b){
	return sqrt(getDis2(a,b));
}

inline bool isEmpty(const Point& a){
	return a.x!=a.x||a.y!=a.y;
}

struct Circle{
	Point o;
	double r;
	inline bool contain(const Point& x)const{
		return sgn(sqr(r)-getDis2(x,o))>=0;
	}
	inline Point getRig(void)const{
		return o+Vector(r,0);
	}
};

inline bool isCon(const Circle& a,const Circle& b){
	return sgn(sqr(a.r-b.r)-getDis2(a.o,b.o))>=0;
}

inline bool isSep(const Circle& a,const Circle& b){
	return sgn(getDis2(a.o,b.o)-sqr(a.r+b.r))>0;
}

inline Point getPot(const Circle &a,const Circle &b){
	if(isCon(a,b))
		if(sgn(b.getRig().x-a.getRig().x)>0)
			return a.getRig();
		else
			return b.getRig();
	else if(isSep(a,b))
		return Point(nan(""),nan(""));
	else{
		if(a.contain(b.getRig()))
			return b.getRig();
		else if(b.contain(a.getRig()))
			return a.getRig();
		else{
			reg double d=getDis(a.o,b.o);
			reg double ang=acos(((sqr(a.r)+sqr(d))-sqr(b.r))/(2*a.r*d));
			reg double delta=atan2(b.o.y-a.o.y,b.o.x-a.o.x);
			reg double ang1=delta+ang,ang2=delta-ang;
			Point p1=a.o+Vector(cos(ang1)*a.r,sin(ang1)*a.r);
			Point p2=a.o+Vector(cos(ang2)*a.r,sin(ang2)*a.r);
			Point res;
			if(sgn(p2.x-p1.x)>0)
				res=p2;
			else
				res=p1;
			return res;
		}
	}
}

int n;
Circle a[MAXN];

int main(void){
	scanf("%d",&n);
	Point lef(0,0);
	for(reg int i=1;i<=n;++i){
		static int x,y,r;
		scanf("%d%d%d",&x,&y,&r);
		a[i].o=Point(x,y),a[i].r=r;
		if(i==2)
			lef=getPot(a[1],a[2]);
		else if(i>2){
			for(reg int j=1;j<i&&!isEmpty(lef);++j){
				Point tmp=getPot(a[i],a[j]);
				if(isEmpty(tmp)||tmp.x<=lef.x)
					lef=tmp;
			}
			for(reg int j=1;j<=i&&!isEmpty(lef);++j)
				if(!a[j].contain(lef))
					lef=Point(nan(""),nan(""));
		}
		if(isEmpty(lef)){
			printf("%d\n",i);
			return 0;
		}
	}
	puts("NIE");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
akc6955是一款芯片,通常用于开发和设计各种电子设备。要进行akc6955的编程,需要以下几个步骤: 1. 硬件准备:使用开发板或者电路设计,并连接至计算机。确保akc6955芯片正常工作并正确连接。 2. 开发环境设置:安装适当的开发环境和软件工具。根据芯片厂商提供的文档,下载并安装相关的开发工具和软件。 3. 编程语言选择:根据自己的需求和经验,选择一个合适的编程语言。常见的编程语言包括C语言、Python等。 4. 芯片手册学习:根据akc6955芯片的技术手册,学习芯片的功能、寄存器、接口等相关知识。熟悉芯片的工作机制和编程原理非常重要。 5. 编写代码:根据自己的需求和目标,在选择的编程语言中开始编写代码。使用所选的开发环境和软件工具,可以根据芯片手册提供的寄存器和接口定义,使用相应的函数和指令来操作和控制akc6955芯片。 6. 调试和测试:完成代码编写后,将代码下载到芯片中进行调试和测试。可以使用调试器、仿真器等工具来帮助定位和修复潜在的问题。 7. 功能优化和性能改进:在初步功能实现的基础上,根据实际需求进行功能优化和性能改进。通过不断调试、测试和改进,确保所编程的akc6955芯片能够按预期工作和表现。 总结来说,要进行akc6955的编程,需要学习和理解相关芯片的技术手册,并选择适当的开发环境和编程语言。然后根据需求编写代码,并不断调试、测试和改进,最终实现所需的功能和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值