专栏文章
题解:P13415 [COCI 2012/2013 #4] VOYAGER
P13415题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio78vht
- 此快照首次捕获于
- 2025/12/02 14:30 3 个月前
- 此快照最后确认于
- 2025/12/02 14:30 3 个月前
首先我们先把方法,思路,算法和优化考虑一下:
1.问题分析:信号在网格中传播,遇到行星('/'或'')会偏转90度,遇到黑洞('C')或边界则停止。我们需要从四个方向(U, R, D, L)中选择一个,使得信号传播的时间最长。
2.关键观察:对于每个方向,模拟信号的传播路径。记录访问过的状态(位置和方向)以检测循环(无限循环)。如果遇到相同的状态(位置和方向)两次,则检测到循环。
3.算法选择:对每个方向进行深度优先搜索(DFS)或迭代模拟,使用记忆化来存储状态(行、列、方向)以避免重复计算和检测循环。
4.优化:由于网格大小最大为500x500,状态总数为4NM(约4500500=1e6),可以在每个方向上进行模拟,使用三维数组vis标记访问过的状态(行、列、方向)以检测循环。
实现细节:
定义方向映射:U(0), R(1), D(2), L(3)。
对于每个起始方向,模拟移动:根据当前方向移动,遇到行星时改变方向(根据行星类型)。
记录步数,如果进入循环则返回"Voyager"。
比较四个方向的步数,选择最大的(按优先级U、R、D、L)。
弄明白以上几点,接下来看一看我的AC代码:
CPP#include<bits/stdc++.h>
using namespace std;
int a[4][2]={{-1,0},{0,1},{1,0},{0,-1}};// U, R, D, L
char b[4]={'U','R','D','L'};
string x[1005];
bool y[1005][1005][4];
bool cmp(int r,int c,int d,int& g,int n,int m){
g=0;
memset(y,false,sizeof(y));
while(true){
if(r<0||r>=n||c<0||c>=m) return false; // 离开网格
if(x[r][c]=='C') return false; // 进入黑洞
if(y[r][c][d]) return true; // 循环
y[r][c][d]=true;
g++;
if(x[r][c]=='/') d=d^1;// 0<->1, 2<->3
else if(x[r][c]=='\\') d = 3 - d; // 0<->3, 1<->2
r += a[d][0];
c += a[d][1];
}
}
int main() {
int n,m,ans,sum,s1=-1,s2=-1;
cin>>n>>m;
for(int i=0;i<n;i++) cin>>x[i];
cin>>ans>>sum;
ans--;
sum--; // 转换为0-indexed
for(int i=0;i<4;i++){
int g=0;
bool k=cmp(ans,sum,i,g,n,m);
if(k==1){
cout<<b[i]<<endl<<"Voyager"<<endl;
return 0;
}
else{
if(g>s1) {
s1=g;
s2=i;
}
}
}
cout<<b[s2]<<endl<<s1<<endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...