P6285 [COCI 2016/2017 #1] Jetpack
题目描述
Mirko 正在玩一款小游戏。在一个 10 10 10 行 n n n 列的矩阵中,他需要从左下角出发,避免在障碍物处停留,最终到达第 n n n 列的任意位置。每秒,他都会向右移动一个单位。
在游戏中,Mirko 拥有一个喷气背包(游戏开始时关闭):
- 打开喷气背包时,每秒他将额外向上移动一个单位(即向右上方移动),直到他处于矩阵顶端的一行。
- 关闭喷气背包时,每秒他将额外向下移动一个单位(即向右下方移动),直到他处于矩阵底端的一行。
他可以在任意一秒打开喷气背包,并在任意秒后关闭。将此记为一次操作。
现在,Mirko 想让你设计一系列操作,使他能够顺利结束游戏。
输入格式
第一行一个整数 n n n,表示矩阵的列数。
接下来
10
10
10 行,每行
n
n
n 个字符。表示相应位置是否存在障碍物。字符只可能是 .
或 X
。
.
表示该区域不存在障碍物。X
表示该区域存在障碍物。
输出格式
本题使用 Special Judge。
第一行一个非负整数 p p p,表示 Mirko 应进行操作的次数。
接下来 p p p 行,每行两个正整数 t i t_i ti 和 x i x_i xi,表示 Mirko 需要在第 t i t_i ti 秒打开喷气背包,并在 x i x_i xi 秒后关闭。
若存在多种答案,请输出任意一种。
另外:
- 操作应按时间顺序给出,且在一次操作完成前无法进行其他操作。即 t i + x i ≤ t i + 1 t_i+x_i\le t_{i+1} ti+xi≤ti+1。
- 游戏结束后 Mirko 无法进行任何操作。即 t i < n t_i<n ti<n。
- Mirko 不希望操作次数过多。即 0 ≤ p ≤ 5 × 10 4 0\le p\le 5\times 10^4 0≤p≤5×104。
输入输出样例 #1
输入 #1
11
.....XX...X
....XX...XX
...XX...XX.
...........
....XXX....
...........
.....X.....
....XX...X.
...XX...XX.
...X...XX..
输出 #1
2
1 4
7 2
输入输出样例 #2
输入 #2
20
X..................X
.X................X.
..X..............X..
...X............X...
....X..........X....
.....X........X.....
......X......X......
.......X....X.......
........X..X........
.........XX.........
输出 #2
1
8 10
说明/提示
样例 1 解释
下图为样例输出一所表示的路径。
.....XX...X
....XX...XX
...XX...XX.
...........
....XXX....
.....*...*.
....*X*.*.*
...*XX.*.X.
..*XX...XX.
**.X...XX..
数据规模与约定
对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 10 5 1\le n\le 10^5 1≤n≤105。
数据保证至少存在一种方案,能使得 Mirko 能够顺利结束游戏。
说明
题目译自 COCI2016-2017 CONTEST #1 T2 Jetpack。
C++实现
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n,out[N][2],cnt;
char a[11][N];
bool v[N],vis;
void init(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i = 1;i<=10;i++)
for(int j = 1;j<=n;j++)
cin>>a[i][j];
}
void print(){
for(int i = 1;i<=n;i++)
if(v[i-1]==0&&v[i])
out[++cnt][0] = i-1,out[cnt][1] = 1;
else if(v[i]) out[cnt][1]++;
cout<<cnt<<'\n';
for(int i = 1;i<=cnt;i++)
cout<<out[i][0]<<' '<<out[i][1]<<'\n';
}
bool dfs(int x,int y){
if(vis) return 1;
if(y==n)
return vis = 1;
if(a[x][y]=='X') return 0;
a[x][y] = 'X';
if(dfs(max(1,x-1),y+1))
return v[y] = 1;
if(vis) return 1;
if(dfs(min(x+1,10),y+1))
return 1;
return vis;
}
int main()
{
init();
dfs(10,1);
print();
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容