1 条题解
-
0
自动搬运
来自洛谷,原作者为

IRipple
刹那余烬,是曾经鲜活跃动的记忆中铭刻至深的梦。搬运于
2025-08-24 21:43:36,当前版本为作者最后更新于2019-04-11 13:15:59,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
很有意思的一道题,做法不是很难。
但是卡住了机房大佬理论分析
模拟一下走的过程。
第一次走的时候我们到起点的上下左右四个方向都需要0个镜子,我们把这些点都记录成第一次的扩展。
//拿样例来举个栗子,不妨设上面的C是起点,另一个是终点 ....... ......C ......* *****.* ....*.. ....*.. .C..*.. .......那么我们标记出第一次可以确定的点
......1 111111C ......* *****.* ....*.. ....*.. .C..*.. .......所有被标记为1的点,都不需要平面镜,我们接着走第二步。
第二步我们把所有标记为1的点进行同样的操作,把这些点的上下左右扩展出来,记录成第二步扩展
2222221 111111C 222222* *****2* ....*2. ....*2. .C..*2. .....2.所有被标记为2的点,都需要1个平面镜。
... ...
像这样我们不断地扩展下去,就会得到到C点所需的镜子个数 0.0
代码实现
首先这种跑地图还问你最短xx的,我们就可以上bfs了。
设计一个结构体
struct node{ int x,y;//点坐标 int num;//记录这个点是第几步扩展得来的 }s,t;然后随手
瞎敲一下bfs就行了void bfs(){ while(!q.empty()){ node u=q.front(),v=u;//u和v都是队首 q.pop(); u.num++; v=u; v.x=u.x-1;//上 dfs(1,v); v=u; v.x=u.x+1;//下 dfs(2,v); v=u; v.y=u.y-1;//左 dfs(3,v); v=u; v.y=u.y+1;//右 dfs(4,v); } }用这个bfs扩展队首点的四个方向,每次dfs去进行染色的工作
void dfs(int fx,node u){ //fx记录方向(1上2下3左4右) u为当前所在点 int x=u.x,y=u.y,p=u.num; if(a[x][y]<p || a[x][y]==inf) return;//如果该点标记比这次扩展的小【即更优】,就直接跳过它。 //inf表示墙,返回 if(x<1 || y<1 || x>n || y>m) return;//超出边界返回 if(fx==1){ a[x][y]=p;//染色 q.push((node){x,y,p});//放入队列,之后进行拓展 dfs(1,(node){x-1,y,p});//染下一个上边的点 } if(fx==2){ a[x][y]=p; q.push((node){x,y,p}); dfs(2,(node){x+1,y,p}); } if(fx==3){ a[x][y]=p; q.push((node){x,y,p}); dfs(3,(node){x,y-1,p}); } if(fx==4){ a[x][y]=p; q.push((node){x,y,p}); dfs(4,(node){x,y+1,p}); } }说明:我把数据给出的地图转成了int类型,inf代表墙。
完整代码如下~
#include<bits/stdc++.h> #include<queue> #define inf 0x3f3f3f3f using namespace std; int n,m; int a[110][110];//保存地图 struct node{ int x,y; int num; }s,t; queue<node> q; void dfs(int fx,node u){ //fx记录方向(1上2下3左4右) u为当前所在点 int x=u.x,y=u.y,p=u.num; if(a[x][y]<p || a[x][y]==inf) return; if(x<1 || y<1 || x>n || y>m) return; if(fx==1){ a[x][y]=p; q.push((node){x,y,p}); dfs(1,(node){x-1,y,p}); } if(fx==2){ a[x][y]=p; q.push((node){x,y,p}); dfs(2,(node){x+1,y,p}); } if(fx==3){ a[x][y]=p; q.push((node){x,y,p}); dfs(3,(node){x,y-1,p}); } if(fx==4){ a[x][y]=p; q.push((node){x,y,p}); dfs(4,(node){x,y+1,p}); } } void bfs(){ while(!q.empty()){ node u=q.front(),v=q.front(); q.pop(); u.num++; v=u; v.x=u.x-1;//上 dfs(1,v); v=u; v.x=u.x+1;//下 dfs(2,v); v=u; v.y=u.y-1;//左 dfs(3,v); v=u; v.y=u.y+1;//右 dfs(4,v); } } int main(){ cin>>m>>n; char zwh; memset(a,inf,sizeof(a)); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) a[i][j]=inf-1; //如果地图范围全部是比答案小的数字(比如0),那么在dfs染色的时候就会直接返回,导致错误。 for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf(" %c",&zwh); if(zwh=='C'){ if(s.x) t.x=i,t.y=j,t.num=0;//找到起点和终点 else s.x=i,s.y=j,s.num=0; } if(zwh=='*'){ a[i][j]=inf; } } } q.push(s); bfs(); cout<<a[t.x][t.y]-1;//注意减一 return 0; }
- 1
信息
- ID
- 2002
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者