洛谷OJ P1141 01迷宫 解题报告
洛谷OJ P1141 01迷宫 解题报告
by MedalPluS
【题目描述】
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
【输入描述】
输入的第1行为两个正整数n,m。
下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。
【输出描述】
输出包括m行,对于每个询问输出相应答案。
【分析】
此题比较坑爹
题目的意思就是求对于一个点所在的联通块的个数
然后笔者想到了并查集和Tarjan
结果看了下范围n<=1000,m<=100000,然后就放弃了。。。
仔细想想其实就是个BFS
然后发现时间复杂度是O(n2m)
然后还是TLE,就要考虑优化了
我们发现,对于一个点所拓展的路径上的所有点能走的格子数是一样的!
那么也就是说,我们可以预处理出整个图
这让我们联想到Flood_fill
然后笔者就采用了DFS的方式
然后就爆栈了,发现对于1000*1000的完全图(全都是1或0)会达到106层,所以必定会爆
这个时候可以考虑采用BFS的方式Flood_fill
然后就TLE了,笔者发现主要拖慢时间的是采取了STL的队列
特别特别的耗时间,然后就手写个队列,再加卡常数的读入
就AC了。。。。
有点淡淡的忧伤
【代码】
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 #define rep(i,l,r) for(i=l;i<=r;i++) 7 #define read scanf 8 #define print printf 9 10 const int maxn=1001; 11 const int maxm=10000001; 12 13 struct xOy{ 14 int x,y; 15 }; 16 17 char graph[maxn][maxn]; 18 int record[maxm],id[maxn][maxn]; 19 xOy q[maxm]; 20 int front,tail; 21 int n,m;//size of the board ; question numbers 22 int datax,datay; 23 24 void bfs(int x,int y,int index){ 25 front=tail=1; 26 tail=2; 27 q[1]=(struct xOy){x,y}; 28 xOy head; 29 while(front!=tail){ 30 head=q[front]; 31 ++front; 32 if(id[head.x][head.y])continue; 33 id[head.x][head.y]=index; 34 record[index]++; 35 if(head.x-1>=1 && graph[head.x-1][head.y]!=graph[head.x][head.y]) 36 q[tail++]=(struct xOy){head.x-1,head.y}; 37 if(head.y-1>=1 && graph[head.x][head.y-1]!=graph[head.x][head.y]) 38 q[tail++]=(struct xOy){head.x,head.y-1}; 39 if(head.x+1<=n && graph[head.x+1][head.y]!=graph[head.x][head.y]) 40 q[tail++]=(struct xOy){head.x+1,head.y}; 41 if(head.y+1<=n && graph[head.x][head.y+1]!=graph[head.x][head.y]) 42 q[tail++]=(struct xOy){head.x,head.y+1}; 43 } 44 } 45 46 int main(){ 47 read("%d%d",&n,&m); 48 int i,j,index=1; 49 rep(i,1,n) 50 rep(j,1,n) 51 cin>>graph[i][j]; 52 rep(i,1,n) 53 rep(j,1,n) 54 { 55 bfs(i,j,index); 56 if(record[index])index++; 57 } 58 rep(i,1,m){ 59 read("%d%d",&datax,&datay); 60 print("%d\n",record[id[datax][datay]]); 61 } 62 return 0; 63 }