2020工大杯题解-D

个人题解,和比赛官方无关,仅供参考

2020工大杯题解 - D - L 同学的又一节体育课

题目描述

迫于忘了选体育课, L同学只能上一个没人选的奇怪的体育课. 在这门课上,
学生被要求玩一个奇怪的游戏, 叫做 “能量传输”. 在这个游戏中, 同学们的目标是组成轨道,
把球从起点传输至筒中, 并保证全程球不能脱轨, 不能把筒撞倒. 全班同学被分成两组, 分别比赛,
之后老师会根据完成小组完成任务的时间的排名来赋予平时分. L同学想要在体育课上内卷,
他想知道需要卷到什么程度. 他偷偷瞄到了另一个组的轨道,
想要问问你另一个组需要多久来完成任务.

一个轨道可以视为一个 8 个长度为 16 的字符串, 如下表示:

1
2
3
4
5
6
7
8
-
\
\
-----
\
\ --
-/ \
V
  • - 表示一个横着摆放的轨道.
  • /\ 分别表示 上升/下降 的斜着摆放的轨道.
  • V 表示目标球桶.
  • 行末最后的空格 可以省略. 如, 上面的字符矩阵中的第一行, 右边省略了15个空格.

为了模拟球的行为, 我们可以认为球有以下属性:

  • 坐标 $\left(x,y\right)$. $x$表示横坐标,$y$表示高度. $1 \leq x \leq 16, 1 \leq y \leq 8$。
    左下角坐标为$\left(1,1\right)$, $x$正方向向上, $y$正方向向右.
  • 速度 v. 不考虑速度的矢量性.

不同摆放的轨道会对于球的速度有如下影响:

  • -: v -= 3
  • \: v += 10
  • /: v -= 15

在运球过程中, 有以下限制:

  • 任意时刻, 球的速度不能超过40, 否则会冲出轨道外.
  • 任意时刻, 球的速度不能小于或等于0, 否则会停止运动.
  • 落入桶中的时候, 球的速度不能超过15, 不然会把桶撞倒.

我们定义球的一次移动为球的横坐标加一的过程. 在球的一次移动中:

  • 如果当前轨道是 \:
    • 如果下一个轨道是 \: 其高度必须比当前轨道少1.
    • 如果下一个轨道是 /: 其高度必须比当前轨道少1.
    • 如果下一个轨道是 -: 其高度必须比当前轨道少1.
    • 如果下一个轨道是 V: 其高度必须比当前轨道少1.
  • 如果当前轨道是 -:
    • 如果下一个轨道是 \: 其高度必须比当前轨道少1.
    • 如果下一个轨道是 /: 其高度必须和当前轨道相同.
    • 如果下一个轨道是 -: 其高度必须和当前轨道相同.
    • 如果下一个轨道是 V: 无论高度如何, 球会脱轨.
  • 如果当前轨道是 /:
    • 如果下一个轨道是 \: 无论高度如何, 球会脱轨.
    • 如果下一个轨道是 /: 其高度必须比当前轨道多1.
    • 如果下一个轨道是 -: 其高度必须比当前轨道多1.
    • 如果下一个轨道是 V: 无论高度如何, 球会脱轨.

为了简化问题, 我们可以如下进行模拟:

  1. 球的初速度为4.
  2. 如果当前轨道是V: 则已经到达终点. 跳转到第六步.
  3. 把通过当前轨道所需时间 $30 / v$ 累加到总时间中. 做除法后保留整数部分.
  4. 通过轨道后, 根据轨道类型, 更新当前速度, 并判断是否可以进入下一个轨道.
  5. 跳转到第二步.
  6. 输出完成任务所需要的总时间. 如果不能完成任务, 请输出-1.

球的初始坐标为 (1, 8), 保证这一格的轨道为 -. 保证坐标为$\left(16, 1\right)$的地方的轨道为V.

输入数据

8 行, 每行一个长度为 16 的字符串, 表示轨道.

保证每列只有一个不是空格的字符, 且其属于 / \ - V

输出数据

一个整数, 代表和 L 同学竞争的组完成任务所需时间.

如果不能完成任务, 请输出-1.

样例输入

1
2
3
4
5
6
7
8
-
\
\
-----
\
\ --
-/ \
V

样例输出

1
80

样例解释

通过每一格的速度分别为:

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};
// -: 0 /: 1 \: 2 v: 3
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){
//cout<<v<<" ";
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;
}