1. 题目描述
  2. 有一个仅由数字01组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
  3. 你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
  4. 输入输出格式
  5. 输入格式:
  6. 输入的第1行为两个正整数nm
  7. 下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
  8. 接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
  9. 输出格式:
  10. 输出包括m行,对于每个询问输出相应答案。
  11. 输入输出样例
  12. 输入样例#1 复制
  13. 2 2
  14. 01
  15. 10
  16. 1 1
  17. 2 2
  18. 输出样例#1 复制
  19. 4
  20. 4
  21. 说明
  22. 所有格子互相可达。
  23. 对于20%的数据,n10
  24. 对于40%的数据,n50
  25. 对于50%的数据,m5
  26. 对于60%的数据,n100m100
  27. 对于100%的数据,n1000m100000

非常艰难..

第一次代码 暴力 70分

  1. #include<iostream>
  2. #include<string>
  3. #include<cstring>
  4. #define MAXN 1005
  5. using namespace std;
  6. int n,m;
  7. int a[MAXN][MAXN];
  8. int b[MAXN][MAXN];
  9. bool vis[MAXN][MAXN];
  10. int c[MAXN][MAXN];
  11. int cnt;
  12. int dx[4]={0,1,0,-1};
  13. int dy[4]={-1,0,1,0};
  14. void dfs(int x,int y){
  15. if(vis[x][y]) return;
  16. if(x<1||x>n||y<1||y>n) return;
  17. vis[x][y]=1;
  18. b[x][y]=1;
  19. cnt++;
  20. for(int i=0;i<=3;i++){
  21. int nx=x+dx[i];
  22. int ny=y+dy[i];
  23. if(a[nx][ny]==a[x][y]) continue;
  24. dfs(nx,ny);
  25. }
  26. }
  27. int calc(){
  28. int s=0;
  29. int i,j;
  30. for(i=1;i<=n;i++){
  31. for(j=1;j<=n;j++){
  32. if(b[i][j]) s++;
  33. }
  34. }
  35. return s;
  36. }
  37. void make(int num){
  38. for(int i=1;i<=n;i++){
  39. for(int j=1;j<=n;j++){
  40. if(b[i][j]) c[i][j]=num;
  41. }
  42. }
  43. }
  44. int main(){
  45. string s;
  46. cin>>n>>m;
  47. int i,j;
  48. for(i=1;i<=n;i++){
  49. cin>>s;
  50. for(j=0;j<n;j++){
  51. a[i][j+1]=s[j]-'0';
  52. }
  53. }
  54. int x,y;
  55. while(m--){
  56. cin>>x>>y;
  57. if(!vis[x][y]){
  58. dfs(x,y);
  59. cnt=calc();
  60. make(cnt);
  61. memset(b,0,sizeof(b));
  62. }
  63. cout<<c[x][y]<<endl;
  64. }
  65. return 0;
  66. }

cin改成scanf,试图写过getchar,不成功 80

  1. #include<iostream>
  2. #include<string>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #define MAXN 1005
  7. using namespace std;
  8. int n,m;
  9. int a[MAXN][MAXN];
  10. int b[MAXN][MAXN];
  11. bool vis[MAXN][MAXN];
  12. int c[MAXN][MAXN];
  13. int cnt;
  14. int dx[4]={0,1,0,-1};
  15. int dy[4]={-1,0,1,0};
  16. void dfs(int x,int y){
  17. if(vis[x][y]) return;
  18. if(x<1||x>n||y<1||y>n) return;
  19. vis[x][y]=1;
  20. b[x][y]=1;
  21. cnt++;
  22. for(int i=0;i<=3;i++){
  23. int nx=x+dx[i];
  24. int ny=y+dy[i];
  25. if(a[nx][ny]==a[x][y]) continue;
  26. dfs(nx,ny);
  27. }
  28. }
  29. int calc(){
  30. int s=0;
  31. for(register int i=1;i<=n;i++){
  32. for(register int j=1;j<=n;j++){
  33. if(b[i][j]) s++;
  34. }
  35. }
  36. return s;
  37. }
  38. void make(int num){
  39. for(register int i=1;i<=n;i++){
  40. for(register int j=1;j<=n;j++){
  41. if(b[i][j]) c[i][j]=num;
  42. }
  43. }
  44. }
  45. int main(){
  46. char s[1005];
  47. scanf("%d%d",&n,&m);
  48. register int i,j;
  49. for(i=1;i<=n;i++){
  50. scanf("%s",s);
  51. for(j=0;j<n;j++){
  52. a[i][j+1]=s[j]-'0';
  53. }
  54. }
  55. // for(int i=1;i<=n;i++){
  56. // for(int j=1;j<=n;j++){
  57. // a[i][j]=getchar()-'0';
  58. // if(a[i][j]<0||a[i][j]>1) j--;
  59. //
  60. // }
  61. // }
  62. int x,y;
  63. while(m--){
  64. cin>>x>>y;
  65. if(!vis[x][y]){
  66. dfs(x,y);
  67. cnt=calc();
  68. make(cnt);
  69. memset(b,0,sizeof(b));
  70. }
  71. printf("%d\n",c[x][y]);
  72. }
  73. return 0;
  74. }

拍脑子一想,cnt在dfs时候就能记录了,没必要再来个n^2的循环。

  1. #include<iostream>
  2. #include<string>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #define MAXN 1005
  7. using namespace std;
  8. int n,m;
  9. int a[MAXN][MAXN];
  10. int b[MAXN][MAXN];
  11. bool vis[MAXN][MAXN];
  12. int c[MAXN][MAXN];
  13. int cnt;
  14. int dx[4]={0,1,0,-1};
  15. int dy[4]={-1,0,1,0};
  16. void dfs(int x,int y){
  17. if(vis[x][y]) return;
  18. if(x<1||x>n||y<1||y>n) return;
  19. vis[x][y]=1;
  20. b[x][y]=1;
  21. cnt++;
  22. for(register int i=0;i<=3;i++){
  23. int nx=x+dx[i];
  24. int ny=y+dy[i];
  25. if(a[nx][ny]==a[x][y]) continue;
  26. dfs(nx,ny);
  27. }
  28. }
  29. int calc(){
  30. int s=0;
  31. for(register int i=1;i<=n;i++){
  32. for(register int j=1;j<=n;j++){
  33. if(b[i][j]) s++;
  34. }
  35. }
  36. return s;
  37. }
  38. inline void make(int num){
  39. for(register int i=1;i<=n;i++){
  40. for(register int j=1;j<=n;j++){
  41. if(b[i][j]) c[i][j]=num;
  42. }
  43. }
  44. }
  45. int main(){
  46. char s[1005];
  47. scanf("%d%d",&n,&m);
  48. register int i,j;
  49. for(i=1;i<=n;i++){
  50. scanf("%s",s);
  51. for(j=0;j<n;j++){
  52. a[i][j+1]=s[j]-'0';
  53. }
  54. }
  55. // for(int i=1;i<=n;i++){
  56. // for(int j=1;j<=n;j++){
  57. // a[i][j]=getchar()-'0';
  58. // if(a[i][j]<0||a[i][j]>1) j--;
  59. //
  60. // }
  61. // }
  62. int x,y;
  63. while(m--){
  64. cin>>x>>y;
  65. if(!vis[x][y]||!c[x][y]){
  66. cnt=0;
  67. dfs(x,y);
  68. // cnt=calc();
  69. make(cnt);
  70. memset(b,0,sizeof(b));
  71. }
  72. printf("%d\n",c[x][y]);
  73. }
  74. return 0;
  75. }

然后想到没必要真的把每个点的值存进二位数组,因为无法同时和dfs完成,必须两步,慢。

但是可以存一个数字进去,在一次dfs中,这个数字代表的是一类点,再用ans数组建立数字和答案(cnt)的映射,但是ans开小了,又RE了一个点。。

AC代码:

  1. #include<iostream>
  2. #include<string>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #define MAXN 1005
  7. using namespace std;
  8. int n,m;
  9. int a[MAXN][MAXN];
  10. int b[MAXN][MAXN];
  11. bool vis[MAXN][MAXN];
  12. int c[MAXN][MAXN];
  13. int cnt;
  14. int dx[4]={0,1,0,-1};
  15. int dy[4]={-1,0,1,0};
  16. int ans[100005];
  17. int p=1;
  18. void dfs(int x,int y){
  19. if(vis[x][y]) return;
  20. if(x<1||x>n||y<1||y>n) return;
  21. vis[x][y]=1;
  22. c[x][y]=p;
  23. cnt++;
  24. for(register int i=0;i<=3;i++){
  25. int nx=x+dx[i];
  26. int ny=y+dy[i];
  27. if(a[nx][ny]==a[x][y]) continue;
  28. dfs(nx,ny);
  29. }
  30. }
  31. int main(){
  32. char s[1005];
  33. scanf("%d%d",&n,&m);
  34. register int i,j;
  35. for(i=1;i<=n;i++){
  36. scanf("%s",s);
  37. for(j=0;j<n;j++){
  38. a[i][j+1]=s[j]-'0';
  39. }
  40. }
  41. int x,y;
  42. while(m--){
  43. cin>>x>>y;
  44. if(!vis[x][y]){
  45. cnt=0;
  46. dfs(x,y);
  47. ans[p]=cnt;
  48. p++;
  49. }
  50. printf("%d\n",ans[c[x][y]]);
  51. }
  52. return 0;
  53. }

[LUOGU]1141 01迷宫的更多相关文章

  1. luogu P1141 01迷宫 x

    P1141 01迷宫 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任 ...

  2. luogu P1141 01迷宫

    https://www.luogu.org/problem/show?pid=1141 还不太会用 BFS 然后就跟着感觉走了一波 经历了很多错误 刚开始的读入 然后BFS的过程 最后T三个点 看到别 ...

  3. Luogu P1141 01迷宫【搜索/dfs】By cellur925

    题目传送门 我tm到现在还需要刷这种水搜索...我退役吧. 但就是搜索弱嘛 补一补嘛qwq 题目大意:给你一张地图与许多询问,每次询问求这个点所在联通块的点的个数. 所以这个题目的本质就是在求联通块. ...

  4. [洛谷Luogu]P1141 01迷宫[联通块 并查集]

    题目链接 大致题意 相邻格子不同为连通,计算每个点所在的连通块大小. 想法 我采用了并查集的做法. 开一个辅助数组记录连通块大小,每次合并的时候更新父亲节点的大小即可. 一个点先与它上面的点判定,若判 ...

  5. [LuoguP1141]01迷宫

    1141 01迷宫 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务 ...

  6. 01迷宫 洛谷 p1141

    题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...

  7. 洛谷——P1141 01迷宫

    P1141 01迷宫 题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任 ...

  8. 【u115】&&【t031】 01迷宫

    01迷宫(maze01) Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相 ...

  9. Codevs 1629 01迷宫

    1629 01迷宫 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可 ...

随机推荐

  1. 【OpenJ_Bailian - 1328】Radar Installation (贪心)

    Radar Installation 原文是English,直接上中文 Descriptions: 假定海岸线是无限长的直线.陆地位于海岸线的一侧,海洋位于另一侧.每个小岛是位于海洋中的一个点.对于任 ...

  2. react native设置容器阴影

    shadowColor:'#eee',shadowOffset:{h:10,w:10},shadowRadius:3,shadowOpacity:0.8,

  3. E. Cyclic Components (DFS)(Codeforces Round #479 (Div. 3))

    #include <bits/stdc++.h> using namespace std; *1e5+; vector<int>p[maxn]; vector<int&g ...

  4. C【C#公共帮助类】分页逻辑处理类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Comm ...

  5. python 基础(十五) socket编程

    SOCKET TCP协议: 有请求 有响应 称之为 tcp协议 是面向连接的协议 就是在收发数据之前 必须先要建立一个可靠的链接 三次握手 如:网站 UDP协议: 是一个非链接的协议 传输之前不需要键 ...

  6. Tinghua Data Mining 8

    聚类 Clustering 根据评论信息做一些聚类,挖掘关系. bug 期望最大法 peek高峰的个数与高斯函数的个数不一定相同 Z隐含参数 不需要求 每个点属于哪个簇 类似于辅助线 跳板 借力 模型 ...

  7. [软件工程基础]2017.11.04 第八次 Scrum 会议

    具体事项 项目交接燃尽图 每人工作内容 成员 已完成的工作 计划完成的工作 工作中遇到的困难 游心 #10 搭建可用的开发测试环境:#9 阅读分析 PhyLab 后端代码与文档:#8 掌握 Larav ...

  8. 洛谷P3603 || bzoj 4763 雪辉 && bzoj4812: [Ynoi2017]由乃打扑克

    https://www.luogu.org/problemnew/show/P3603 https://www.lydsy.com/JudgeOnline/problem.php?id=4763 就是 ...

  9. 4、重建二叉树------------>剑指offer系列

    题目1-二叉树重建 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序 ...

  10. Android recyclerview 只显示一行 宽度不适配

    最近学习recyclerview 遇到的问题 1.宽度不适配 正确写法 LayoutInflater.from(context).inflate(R.layout.item_view,parent,f ...