海上逃亡
来源:互联网 发布:windows安装bugfree 编辑:程序博客网 时间:2024/04/28 15:46
海上逃亡
【问题描述】
你在海上逃亡!敌人随时都可能发现你!他们拥有着强大的雷达系统,和超远距离的导弹
系统。现在有一个好消息和一个坏消息:
好消息是:敌人的雷达系统是有范围限制的,因此只要你离开现在所在的位置尽量遥远,
就有希望能够逃脱。而坏消息是:你现在拥有的唯一的一艘战舰是从敌人营地中偷出的,他们
为了安全考虑编码了船的指令系统,使得你只能执行一些预设置的行船命令各一次。
这些命令在一些特定的组合下能够到达敌人希望到达的任何地方;但是此时的你,只希望
能够从中组合出一个能够尽量远离此处的序列:
right X:其中 X 是一个 1 到 719 的整数,这个命令使得船顺时针转动 X 度。
left X:其中 X 是一个 1 到 719 的整数,这个命令使得船逆时针转动 X 度。
forward X:其中 X 是一个整数(1 到 10 3 ),使得船向正前方前进 X 的距离。
backward X:其中 X 是一个整数(1 到 10 3 ),使得船向正后方前进 X 的距离。
你可以以任意的顺序执行这一些命令,但是每一命令只能执行一次。
【输入格式】
输入文件名为 ship.in。
第一行一个整数 n,敌人预编码的命令数。
接下来 n 行,每行表示一个命令。
【输出格式】
输出文件名为 ship.out。
一个浮点数,能够逃离的最远的距离,四舍五入到 6 位小数。
【输入输出样例】
见选手目录下的 ship/ship.in 和 ship/ship.ans。
【数据规模与约定】
对于 30%的数据,1≤n≤10。
对于 100%的数据,1≤n≤50。
【问题简述】
给定一个长度为 N 的指令序列,其中包括前进、后退、转弯。找到一个排序,使得离开距离最远。所有指令需且只能执行一次。
【数据规模与约定】
对于 30%的数据,1≤n≤10。
对于 100%的数据,1≤n≤50。
【可能的算法】
对于 30%的数据,可以直接进行暴力搜索,枚举所有可能的排列方式,取得其中离开最远
的指令方案。时间复杂度 O(n!)
对于 100%的数据,我们可以注意到在最开始和最结束的地方进行转弯是没有影响的,意
味着我们可以只选择其中的一部分转弯指令。并且我们不会选择在前进一段距离之后转弯再前
进一段距离,或是后退一段距离后转弯再后退——因为这必然使得距离原点距离不优(注意到原点角度无关)。同理先前进或是先后退也是对称的。
问题可以直接简化为:前进所有能前进的距离,之后转一个可选的角度,然后后退所有能
后退的距离。对于选择角度的旋转,我们可以通过类似动态规划的方法转移出所有可能转动的
总角度,最多有 360 种,利用余弦定理计算出第三边长。(c 2 = a 2 + b 2 - 2abcos(angle))
偷懒的做法:可以在这 360 种中枚举,选择一个最优解即可。
这便是这道题的满分算法。时间复杂度 O(n)。
代码
#include<cstdio>#include<algorithm>#include<cstring>#include<math.h>const int All = 360;int n;int forward[51], backward[51], left[51];int lenF, lenB, lenL;int front, back;bool angle[365], f[365];int main(void){ freopen("ship.in", "r",stdin); freopen("ship.out", "w",stdout); scanf("%d", &n); for(int i = 1;i<=n;i++){ char str[10]; scanf("%s", str); if(strcmp(str, "forward") == 0) scanf("%d", &forward[++lenF]); else if(strcmp(str, "backward") == 0) scanf("%d", &backward[++lenB]); else if(strcmp(str, "left") == 0) scanf("%d", &left[++lenL]); else if(strcmp(str, "right") == 0){ scanf("%d", &left[++lenL]); left[lenL] = - left[lenL]; } } for(int i = 1;i<=lenF;i++) front += forward[i]; for(int i = 1;i<=lenB;i++) back += backward[i]; angle[0] = 1, f[0] = 1; for(int i = 1;i<=lenL;i++){ for(int j = 0;j<360;j++) if(angle[j]) f[(j+All+left[i]) % All] = 1; for(int j = 0;j<360;j++) angle[j] = f[j]; } int maxAngle = 0; for(int i = 0;i<=180;i++){ if(angle[180+i] || angle[180-i]){ maxAngle = i; break; } } double max = 0; max = sqrt(pow(front + back*cos(M_PI*(double)maxAngle/180), 2) + pow(back*sin(M_PI*(double)maxAngle/180), 2)); printf("%.6llf", max); return 0;}... prompt'''
- 海上逃亡
- 逃亡
- 《海上钢琴师》
- 海上名山
- 海上钢琴师
- 海上钢琴师
- 海上钢琴师
- 海上钢琴师
- 海上花 思过崖
- 我看《海上花》
- 南海海上观音
- 《海上钢琴师》略读
- 心房建造在海上
- 海上钢琴家 与程序员
- 海上漂泊的我
- 海上之旅
- 看海上钢琴师有感
- 海上钢琴师经典台词
- 推荐一些非常有用的学习网站
- 线程编程方面
- 使用代码检查工具解决C++潜在的bug
- Caffe源码解析4: Data_layer
- Ionic开发入门教程_1
- 海上逃亡
- 有感:应聘Java笔试时可能出现问题及其答案
- selenium-Java-使用csv文件进行数据驱动-中文乱码
- 数据仓库的基本架构
- Node.js初步认识
- MG动画实例——旋转的地球
- mysql 存储过程
- 【转载】session和cookie的区别和联系,session的生命周期
- Makefile经典教程(掌握这些足够)