个人题解,和比赛官方无关,仅供参考
2020工大杯题解- D - L同学的又一节体育课
题目描述
迫于忘了选体育课, L同学只能上一个没人选的奇怪的体育课.在这门课上,
学生被要求玩一个奇怪的游戏,叫做 “能量传输”.在这个游戏中,同学们的目标是组成轨道,
把球从起点传输至筒中,并保证全程球不能脱轨,不能把筒撞倒.全班同学被分成两组,分别比赛,
之后老师会根据完成小组完成任务的时间的排名来赋予平时分. L同学想要在体育课上内卷,
他想知道需要卷到什么程度.他偷偷瞄到了另一个组的轨道,
想要问问你另一个组需要多久来完成任务.
一个轨道可以视为一个8个长度为16的字符串,如下表示:
1 2 3 4 5 6 7 8
| - \ \ ----- \ \ -- -/ \ V
|
-
表示一个横着摆放的轨道.
/
和 \
分别表示 上升/下降 的斜着摆放的轨道.
V
表示目标球桶.
- 行末最后的空格 可以省略.如,上面的字符矩阵中的第一行,右边省略了15个空格.
为了模拟球的行为,我们可以认为球有以下属性:
- 坐标. 表示横坐标,表示高度. 。
左下角坐标为, 正方向向上, 正方向向右.
- 速度v.不考虑速度的矢量性.
不同摆放的轨道会对于球的速度有如下影响:
-
: v -= 3
\
: v += 10
/
: v -= 15
在运球过程中,有以下限制:
- 任意时刻,球的速度不能超过40,否则会冲出轨道外.
- 任意时刻,球的速度不能小于或等于0,否则会停止运动.
- 落入桶中的时候,球的速度不能超过15,不然会把桶撞倒.
我们定义球的一次移动为球的横坐标加一的过程.在球的一次移动中:
- 如果当前轨道是
\
:
- 如果下一个轨道是
\
:其高度必须比当前轨道少1.
- 如果下一个轨道是
/
:其高度必须比当前轨道少1.
- 如果下一个轨道是
-
:其高度必须比当前轨道少1.
- 如果下一个轨道是
V
:其高度必须比当前轨道少1.
- 如果当前轨道是
-
:
- 如果下一个轨道是
\
:其高度必须比当前轨道少1.
- 如果下一个轨道是
/
:其高度必须和当前轨道相同.
- 如果下一个轨道是
-
:其高度必须和当前轨道相同.
- 如果下一个轨道是
V
:无论高度如何,球会脱轨.
- 如果当前轨道是
/
:
- 如果下一个轨道是
\
:无论高度如何,球会脱轨.
- 如果下一个轨道是
/
:其高度必须比当前轨道多1.
- 如果下一个轨道是
-
:其高度必须比当前轨道多1.
- 如果下一个轨道是
V
:无论高度如何,球会脱轨.
为了简化问题,我们可以如下进行模拟:
- 球的初速度为4.
- 如果当前轨道是
V
:则已经到达终点.跳转到第六步.
- 把通过当前轨道所需时间累加到总时间中.做除法后保留整数部分.
- 通过轨道后,根据轨道类型,更新当前速度,并判断是否可以进入下一个轨道.
- 跳转到第二步.
- 输出完成任务所需要的总时间.如果不能完成任务,请输出-1.
球的初始坐标为(1, 8),保证这一格的轨道为-
.保证坐标为的地方的轨道为V
.
输入数据
8行,每行一个长度为16的字符串,表示轨道.
保证每列只有一个不是空格的字符,且其属于 /
\
-
V
输出数据
一个整数,代表和L同学竞争的组完成任务所需时间.
如果不能完成任务,请输出-1
.
样例输入
1 2 3 4 5 6 7 8
| - \ \ ----- \ \ -- -/ \ V
|
样例输出
样例解释
通过每一格的速度分别为:
4 1 11 21 18 15 12 9 6 16 26 23 8 5 2
所需时间分别为
7 30 2 1 1 2 2 3 5 1 1 1 3 6 15
题解
题目重述
大模拟题,暴力模拟即可,考察细节。
题目解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <iostream> #include <string> using namespace std;
int main(){ int height[17] = {0}; int type[17] = {0}; int delta_V[4] = {-3,-15,10,0}; string now; for(int i = 0; i < 8; ++ i){ getline(cin, now); int j = 0; for(char &c: now){ switch(c){ case '-': height[j+1] = 8 - i; type[j+1] = 0; break; case '/': height[j+1] = 8 - i; type[j+1] = 1; break; case '\\': height[j+1] = 8 - i; type[j+1] = 2; break; case 'V': height[j+1] = 8 - i; type[j+1] = 3; break; default: break; } j++; } } int v = 4; int x = 1; int y = 8; int t = 0; while(true){ if(type[x] == 3){ if(v > 15){ t = -1; } break; } if(v > 40 or v <= 0){ t = -1; break; } t += (30 / v); if(type[x] == 0){ if(type[x+1] == 0){ if(height[x+1] != height[x]){ t = -1; break; } }else if(type[x+1] == 1){ if(height[x+1] != height[x]){ t = -1; break; } }else if(type[x+1] == 2){ if(height[x+1] != height[x]-1){ t = -1; break; } else { y -= 1; } }else if(type[x+1] == 3) { t = -1; break; } }else if(type[x] == 1) { if(type[x+1] == 0) { if(height[x+1] != height[x] + 1){ t = -1; break; } else { y += 1; }; }else if(type[x+1] == 1) { if(height[x+1] != height[x] + 1){ t = -1; break; } else { y += 1; }; }else if(type[x+1] == 2) { t = -1; break; }else if(type[x+1] == 3){ t = -1; break; } }else if(type[x] == 2) { if(height[x+1] != height[x] - 1){ t = -1; break; } y -= 1; } v += delta_V[type[x]]; x++; } cout<<t<<endl; return 0; }
|