鱼C论坛

 找回密码
 立即注册
查看: 1892|回复: 5

[求助] 01迷宫

[复制链接]
发表于 2022-6-11 16:09:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 柿子饼同学 于 2022-6-11 18:19 编辑

题目在下边~
我的代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. bool vis[1002][100002]; // 访问后的标记数组
  4. int areas[1002][100002]; // 联通区域的图
  5. bool mp[1002][100002]; // 存放迷宫
  6. short dirx[] = {1, 0, -1, 0}; // x的4个方向
  7. short diry[] = {0, 1, 0, -1}; // y的4个方向
  8. int n, m, cnt = 1; // n, m -> 长, 宽
  9. queue<int> x; // x, y 的队列 , 用宽搜的
  10. queue<int> y;
  11. map<int, int> cnts; // 每个区域对应的步数, <区域名, 步数>

  12. void bfs(int px, int py){
  13.     static int cnt = 1; // cnt -> 标记不同联通的区域
  14.     int ans = 1; //步数初始化为 1
  15.     x.push(px); y.push(py); vis[px][py] = 1;
  16.     while(!x.empty()){
  17.         for(int i = 0; i < 4; i++){
  18.             int dx = x.front() + dirx[i];
  19.             int dy = y.front() + diry[i];
  20.             if(dx > 0 && dx <= n && dy > 0 && dy <= m && vis[dx][dy] == 0 && mp[dx][dy] != mp[x.front()][y.front()]){
  21.                 x.push(dx); y.push(dy); vis[dx][dy] = 1; // 符合条件入队
  22.                 areas[dx][dy] = cnt; // 给它标号
  23.             }
  24.         }
  25.         ans++; // 每次搜索步数加 1
  26.     }
  27.     cnts[cnt] = ans; // 最后这个连通块的步数就求好了
  28.     cnt++; // 下一个连通块的号加 1
  29. }

  30. void makeareas(){ // 把整个迷宫的不同联通区域弄出来
  31.     for(int i = 1; i <= n; i++){
  32.         for(int j = 1; j <= m; j++){
  33.             if(!vis[i][j]) bfs(i, j); //没访问过就访问
  34.         }
  35.     }
  36. }

  37. int main(){
  38.     ios::sync_with_stdio(0);

  39.     memset(vis, 0, sizeof(vis));
  40.    
  41.     cin >> n >> m;
  42.     for(int i = 1; i <= n; i++){
  43.         for(int j = 1; j <= m; j++){
  44.             char temp;
  45.             cin >> temp;
  46.             mp[i][j] = (bool)(temp - '0');
  47.         }
  48.     } // 输入 , 因为只有 0 和 1 , 所以省空间就用了 bool 存

  49.     makeareas();

  50.     for(int i = 0; i < m; i++){
  51.         int p, q;
  52.         cin >> p >> q;
  53.         cout << cnts[areas[p][q]] << endl;
  54.     } // 输出 , 把它所在的连通块的标号求出 , 然后就可以知道步数 , 输出

  55.     return 0;
  56. }
复制代码

题目 : https://www.luogu.com.cn/problem/P1141
代码检查不出来, 到输入坐标的时候输不进去, 救助
另外我这个代码还有哪里有不好的地方请指出, 谢谢~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-6-11 18:17:55 | 显示全部楼层

救救我吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-11 18:58:43 | 显示全部楼层
我的思路:
用递归吧,走过的路线标记起来,当上下左右没有路线时,则返回最终步数,并且找出上下左右最长的路线便是答案。

递:用来算步数
归:用来比较最大值
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-11 19:58:05 | 显示全部楼层
本帖最后由 jhq999 于 2022-6-11 19:59 编辑
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int makeareas(int (*mp)[2],int n,int x,int y,int len,int *max)
  4. {
  5.     int i,j;
  6.     if(mp[x*n+y][0]^mp[x*n+y+1][0]&&(0==mp[x*n+y+1][1])&&(y+1<n))
  7.     {
  8.         mp[x*n+y+1][1]=1;
  9.         makeareas(mp,n,x,y+1,len+1,max);
  10.         mp[x*n+y+1][1]=0;
  11.     }
  12.     if(mp[x*n+y][0]^mp[x*n+y-1][0]&&(0==mp[x*n+y-1][1])&&(y-1>=0))
  13.     {
  14.         mp[x*n+y-1][1]=1;
  15.         makeareas(mp,n,x,y-1,len+1,max);
  16.         mp[x*n+y-1][1]=0;
  17.     }
  18.     if(mp[x*n+y][0]^mp[(x+1)*n+y][0]&&(0==mp[(x+1)*n+y][1])&&(x+1<n))
  19.     {
  20.         mp[(x+1)*n+y][1]=1;
  21.         makeareas(mp,n,x+1,y,len+1,max);
  22.         mp[(x+1)*n+y][1]=0;
  23.     }
  24.      if(mp[x*n+y][0]^mp[(x-1)*n+y][0]&&(0==mp[(x-1)*n+y][1])&&(x-1>=0))
  25.     {
  26.         mp[(x-1)*n+y][1]=1;
  27.         makeareas(mp,n,x-1,y,len+1,max);
  28.         mp[(x-1)*n+y][1]=0;
  29.     }
  30.     if(*max<len)*max=len;
  31.     return 0;
  32. }
  33. int main(){
  34.     ios::sync_with_stdio(0);
  35.     int n,m,i,j;
  36.     cin >> n >> m;
  37.     int (*mp)[2]=(int(*)[2])malloc(sizeof(int)*n*n*2);
  38.     for(i=0;i<n;i++)
  39.     {
  40.         for(j=0;j<n;j++)
  41.         {
  42.             cin>>mp[i*n+j][0];
  43.             mp[i*n+j][1]=0;
  44.         }
  45.     }
  46.     int max=0;
  47.     mp[0][1]=1;
  48.     makeareas(mp,n,0,0,1,&max);
  49.     // 输入 , 因为只有 0 和 1 , 所以省空间就用了 bool 存

  50.     //makeareas();
  51.     printf("%d",max);
  52.     free(mp);
  53.     return 0;
  54. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-6-11 22:29:05 | 显示全部楼层
傻眼貓咪 发表于 2022-6-11 18:58
我的思路:
用递归吧,走过的路线标记起来,当上下左右没有路线时,则返回最终步数,并且找出上下左右最长 ...

可是它要搜十万次...
这不行吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-6-11 22:49:24 | 显示全部楼层
柿子饼同学 发表于 2022-6-11 22:29
可是它要搜十万次...
这不行吧

好象也是
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-24 05:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表