北邮机试 | bupt oj | 102. 最远距离 | 贪心算法&局部最优

最远距离

时间限制 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

AC代码

思路:最佳为朝一个方向走不拐弯。在有前进后退两个指令的时候通过将不同拐弯指令排列出来,选择最接近180°角的方向使前进后退尽可能朝一个方向!

#include<bits/stdc++.h>
using namespace std;
#define For(i,m,n) for(int i=m;i<n;i++)
const double pi=acos(-1);
using namespace std;
char director[20];
void init(char *director,vector<int> &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<int> AnglesPremutation(vector<int> Angles){
    set<int> rec;
    int a_size = Angles.size();
    For(i,0,a_size){
        vector<int> 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<int> rec,int fw,int bw){
    int minA=180;
    set<int>::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<int> Angles;
        init(director,Angles,n,fw,bw);
        set<int> rec = AnglesPremutation(Angles);
        double ans = getMax(rec,fw,bw);
        printf("%.3f\n",ans);
    }
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值