NC219148. 牛牛的robot
描述
牛牛有一个用树莓派做的机器人小车,牛牛请你为它编写一个寻路程序。
小车一开始在坐标原点(0,0)的位置,牛牛已经预先烧录进去了一个向量序列,向量序列的大小为n,序列中第i个元素为。
输入描述
第一行输入一个正整数n()表示向量序列的大小,接下来n行每行两个整数()表示向量序列的第i个向量。保证输入的向量不为0向量。接下来一个正整数m()表示有m个查询,每个查询彼此独立(每个查询中小车的起点均为0,0,不会随着查询而改变)。接下来m行,每行两个整数()表示第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
说明:
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; }