列表

详情


NC219148. 牛牛的robot

描述

牛牛有一个用树莓派做的机器人小车,牛牛请你为它编写一个寻路程序。
小车一开始在坐标原点(0,0)的位置,牛牛已经预先烧录进去了一个向量序列,向量序列的大小为n,序列中第i个元素为

小车寻路程序的工作原理是这样的,寻路AI试图生成一个大小为n的实数指令序列,且中每个元素的大小均在[-1,1]之间,序列的第i个元素为c_i,使得机器人从原点开始依次执行移动的动作后能够到达目标地点。

对于一个实数乘以一个向量,其结果是一个新的向量

以二维坐标上的某点p(x_0,y_0)为起点移动一个向量,移动后位于一个新的坐标

如果存在这样一个实数指令序列满足小车移动后可以达到目标地点,那么小车将的寻路程序会显"yes"并且返回一个合法的指令序列,注意合法的指令序列是指中每个元素的大小均在[-1,1]之间。
否则如果不存在任何一个指令序列能够使得小车移动到目标地点,那么寻路程序将只会显示"no"。


输入描述

第一行输入一个正整数n()表示向量序列的大小,接下来n行每行两个整数x_i,y_i()表示向量序列的第i个向量。保证输入的向量不为0向量。

接下来一个正整数m()表示有m个查询,每个查询彼此独立(每个查询中小车的起点均为0,0,不会随着查询而改变)。

接下来m行,每行两个整数qx_i,qy_i()表示第i个查询的目标地点。

输入数据保证,即最终的输出文本量在级别。

输出描述

对于每个查询,如果存在一个合法的实数指令序列coef,则先输出"yes",然后接下来一行输出n个大小范围在[-1,1]之间的实数,表示指令序列,注意输出的实数之间用空格隔开,否则只需输出"no"。

当合法的实数指令序列不唯一时,你可以任意输出一种。

对于小车实际可达的目标点,你的答案正确,当且仅当小车按照你提供的指令序列进行移动后,最终停留位置距离目标点的欧几里得距离小于

示例1

输入:

3
3 0
1 1
0 2
4
3 2
-4 1
0 0
4 4

输出:

yes
1.0 0.0 1.0
yes
-1 -1 1
yes
0 0 0
no

说明:

查询1

查询2

查询3

对于查询3,以下答案也是可行的结果

对于查询4,小车无法到达。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 390ms, 内存消耗: 18552K, 提交时间: 2021-03-27 15:37:52

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
typedef long double db;
const int N=100500,INF=1e9;
const db PI=acos(-1),ESP=1e-3;
int read(int &n)
{
	bool q=0;char ch=' ';n=0;
	for(;ch!='-'&&(ch<'0'||ch>'9');ch=getchar());
	if(ch=='-')q=1,ch=getchar();
	for(;ch<='9'&&ch>='0';ch=getchar())n=(n<<1)+(n<<3)+ch-48;
	return q?n=-n:n;
}
int n,m;
struct Val
{
	int x,y;
	db v,v1,v2;
}a[N];
db Ans[N];
int p[N];
bool PX(int q,int w){
	return a[q].v2>a[w].v2;
}
// db abs(db q){return q<0?-q:q;}
int main()
{
	int q,w,_;
	read(n);
	fo(i,1,n)
	{
		read(a[i].x),read(a[i].y);
		a[i].v=atan2(a[i].x,a[i].y);
		// printf("%.6lf\n",a[i].v);
	}
	read(m);
	fo(I,1,m)
	{
		db X,Y,k;
		scanf("%Lf%Lf",&X,&Y);
		if(X==0&&Y==0)
		{
			printf("yes\n");
			fo(i,1,n)printf("0 ");printf("\n");
			continue;
		}
		k=atan2(X,Y);
		db nx=0,ny=0;
		fo(i,1,n)
		{
			a[i].v1=a[i].v-k;
			if(a[i].v1>PI)
			{
				a[i].v1=a[i].v1-2*PI;
			}
			if(a[i].v1<-PI)
			{
				a[i].v1+=2*PI;
			}
			a[i].v2=min(abs(a[i].v1),PI-abs(a[i].v1));
		}
		fo(i,1,n)
		{
			if(abs(a[i].v1)*2<PI)
			{
				nx+=a[i].x;
				ny+=a[i].y;
				Ans[i]=1;
			}else {
				nx-=a[i].x;
				ny-=a[i].y;
				Ans[i]=-1;
			}
		}
		db ori=(ny*X-Y*nx);
		p[0]=0;
		if(ori<0)
		{
			fo(i,1,n)if((a[i].v1>0 && a[i].v1<PI/2)||(a[i].v1<-PI/2))p[++p[0]]=i;
		}else if(ori>0){
			fo(i,1,n)if((a[i].v1<0 && a[i].v1>-PI/2)||(a[i].v1>PI/2))p[++p[0]]=i;
		}
		sort(p+1,p+1+p[0],PX);

		fo(i,1,p[0])
		{
			q=p[i];
			if((a[q].x*Y-a[q].y*X)==0)break;

			nx-=a[q].x*Ans[q]*2;
			ny-=a[q].y*Ans[q]*2;
			Ans[q]=-Ans[q];
			if(ori*(ny*X-Y*nx)<=0)
			{

				nx-=a[q].x*Ans[q];
				ny-=a[q].y*Ans[q];

				Ans[q]=(X*ny-Y*nx)/(a[q].x*Y-a[q].y*X);
				nx+=a[q].x*Ans[q];
				ny+=a[q].y*Ans[q];
				
				break;
			}
		}
		if(abs(ny*X-Y*nx)>ESP || (nx==0 && ny==0))
		{
			// printf("%.15LF\n",ny*X-Y*nx);
			// cerr<<ny*X-Y*nx<<endl;
			printf("no\n");
			continue;
		}
		db t=sqrt((X*X+Y*Y)/(nx*nx+ny*ny));
		if(t>1)
		{
			printf("no\n");
			continue;
		}
		printf("yes\n");
		fo(i,1,n)printf("%.15Lf ",Ans[i]*t);
		printf("\n");
	}
	return 0;
}

上一题