时间限制 1000 ms 内存限制 65536 KB
正义的伙伴褋祈和葬仪社的机器人Fuyuneru正在被邪恶的GHQ部队追杀。眼看着快要逃不掉了,祈就把重要的东西塞到了机器人体内,让它先跑,自己吸引火力。
假设Fuyuneru带上东西开始逃跑时所处的点为原点,朝向为正北。操纵FuyuNeru的指令有如下四种:
right X: X是1-359之间的整数,Fuyuneru的前进方向顺时针转X度。
left X: X是1-359之间的整数,Fuyuneru的前进方向逆时针转X度。
forward X: X是整数(0<=X<=1000),Fuyuneru向当前朝向前进X米。
backward X: X是整数(0<=X<=1000),Fuyuneru向当前朝向后退X米。
现在祈向Fuyuneru体内输入了N(1<=N<=50)个这样的指令。可是由于此前Fuyuneru被GHQ部队击中,它出了一点小问题:这N个指令执行的顺序是不确定的。
问:Fuyuneru最远可能逃出多远?
即,Fuyuneru在执行完N条指令之后,距离原点最远的可能距离是多少?
第一行是一个整数T,代表测试数据有T组。
每组测试数据中,第一行是一个整数N,代表指令有N条;
随后紧跟N行,每一行代表一个指令(格式保证是上述四种中的一种,数据保证合法)
对于每组数据,输出一行:最远的可能逃亡距离,精确到小数点后3位。
3
3
forward 100
backward 100
left 90
4
left 45
forward 100
right 45
forward 100
6
left 10
forward 40
right 30
left 10
backward 4
forward 4
141.421
200.000
40.585
思路:最佳为朝一个方向走不拐弯。在有前进后退两个指令的时候通过将不同拐弯指令排列出来,选择最接近180°角的方向使前进后退尽可能朝一个方向!
#include
using namespace std;
#define For(i,m,n) for(int i=m;i &Angles,int n,int &fw,int &bw){
int d;
while(n--){
scanf("%s",director);
scanf("%d",&d);
if(director[0]=='f'){
fw+=d;
}
else if(director[0]=='b'){
bw+=d;
}
else if(director[0]=='l'){
Angles.push_back(360-d);
}
else{
Angles.push_back(d);
}
}
}
set AnglesPremutation(vector Angles){
set rec;
int a_size = Angles.size();
For(i,0,a_size){
vector tmp(rec.begin(),rec.end());
int r_size = rec.size();
For(j,0,r_size) {
rec.insert((tmp[j]+Angles[i])%360);
}
rec.insert(Angles[i]);
}
return rec;
}
double getMax(set rec,int fw,int bw){
int minA=180;
set::iterator it=rec.begin();
while(it!=rec.end()){
int a= *it;
int delta=abs(a-180);
minA=min(delta,minA);
it++;
}
double A=fw,B=bw;
double rad=((180.-minA)/180.)*pi;
double ans=sqrt(A*A+B*B-2*A*B*cos(rad));
return ans;
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int fw=0,bw=0;
vector Angles;
init(director,Angles,n,fw,bw);
set rec = AnglesPremutation(Angles);
double ans = getMax(rec,fw,bw);
printf("%.3f\n",ans);
}
return 0;
}