1. 程式人生 > >P1141 01迷宮

P1141 01迷宮

class void 所有 題目 close else 入隊 main 之間

題目描述

有一個僅由數字0與1組成的n×n格迷宮。若你位於一格0上,那麽你可以移動到相鄰4格中的某一格1上,同樣若你位於一格1上,那麽你可以移動到相鄰4格中的某一格0上。

你的任務是:對於給定的迷宮,詢問從某一格開始能移動到多少個格子(包含自身)。

輸入輸出格式

輸入格式:

輸入的第1行為兩個正整數n,m。

下面n行,每行n個字符,字符只可能是0或者1,字符之間沒有空格。

接下來m行,每行2個用空格分隔的正整數i,j,對應了迷宮中第i行第j列的一個格子,詢問從這一格開始能移動到多少格。

輸出格式:

輸出包括m行,對於每個詢問輸出相應答案。

輸入輸出樣例

輸入樣例#1:
2 2
01
10
1 1
2 2
輸出樣例#1:
4
4

說明

所有格子互相可達。

對於20%的數據,n≤10;

對於40%的數據,n≤50;

對於50%的數據,m≤5;

對於60%的數據,n≤100,m≤100;

對於100%的數據,n≤1000,m≤100000。

技術分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5
using namespace std; 6 int will=0; 7 struct node 8 { 9 int x,y; 10 int step; 11 int p; 12 }cur; 13 int n,m; 14 int vis[1001][1001]; 15 int a[1001][1001]; 16 int xx[6]={-1,+1,0,0}; 17 int yy[6]={0,0,-1,+1}; 18 int tot[1001]; 19 void BFS(int bgx,int bgy,int cs) 20 { 21 int ans=1;
22 memset(vis,0,sizeof(vis)); 23 vis[bgx][bgy]=cs; 24 cur.x=bgx;cur.y=bgy;cur.step=1;cur.p=a[bgx][bgy]; 25 queue<node>q; 26 q.push(cur); 27 while(q.size()!=0) 28 { 29 node now=q.front(); 30 q.pop(); 31 if(now.p==0)will=1; 32 else will=0; 33 for(int i=0;i<4;i++) 34 { 35 int wx=now.x+xx[i]; 36 int wy=now.y+yy[i]; 37 if(vis[wx][wy]==0&&wx>=1&&wx<=n&&wy>=1&&wy<=n&&a[now.x][now.y]!=a[wx][wy]) 38 { 39 node nxt; 40 vis[wx][wy]=cs; 41 nxt.x=wx;nxt.y=wy;nxt.step=now.step+1;nxt.p=will; 42 ans++; 43 q.push(nxt); 44 } 45 } 46 } 47 tot[cs]=ans; 48 return ; 49 } 50 int main() 51 { 52 string z; 53 scanf("%d%d",&n,&m); 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=n;j++) 56 a[i][j]=-1; 57 for(int i=1;i<=n;i++) 58 { 59 cin>>z; 60 for(int k=0;k<z.length();k++) 61 a[i][k+1]=z[k]-48; 62 } 63 64 for(int i=1;i<=m;i++) 65 { 66 int x,y; 67 scanf("%d%d",&x,&y); 68 if(vis[x][y]==0) 69 BFS(x,y,i); 70 else 71 tot[i]=tot[vis[x][y]]; 72 } 73 for(int i=1;i<=m;i++) 74 printf("%d\n",tot[i]); 75 return 0; 76 }
不知道為什麽會超時的代碼 技術分享
 1 #include <iostream>
 2 #include <queue>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 bool matrix[1005][1005];//代表矩陣(0/1);
 7 int vis[1005][1005];//vis數組中存這個點在第幾次搜索中訪問過
 8 int dx[4]={0,0,1,-1};//行變化量
 9 int dy[4]={-1,1,0,0};//列變化量
10 int n,m;//m行n列
11 long int ans[1000000];//第ans[i]為第i次搜索的結果
12 queue <int> qx,qy;//行隊列,列隊列
13 int x,y;
14 queue <bool>now;//狀態隊列(當前所處的點是0還是1)
15 void bfs(int turn,int i,int j)//從點(i,j)開始進行第turn次搜索(turn為所給出的第幾個數據)
16 {
17     qx.push(i);//初始點入隊
18     qy.push(j);
19     vis[i][j]=turn;//這個點在第turn次搜索中訪問過
20     now.push(matrix[i][j]);//當前狀態入隊
21     long int sum=1;//sum為可到達的點數
22     while(!qx.empty())//隊非空
23     {
24         for(int w=0;w<4;w++)//四種走法
25         {
26             int a=qx.front()+dx[w];
27             int b=qy.front()+dy[w];
28             if(a>=1&&a<=n&&b>=1&&b<=n&&!vis[a][b]&&matrix[a][b]!=now.front())//若滿足條件(註:若vsi[a][b]非零則真,本次搜索結果不可能包括曾經到過的點)
29             {
30                 qx.push(a);
31                 qy.push(b);//點入隊
32                 now.push(matrix[a][b]);//狀態入隊
33                 sum++;//點數加一
34                 vis[a][b]=turn;//該點在第turn次搜索中訪問過
35             }
36         }
37         qx.pop();
38         qy.pop();
39         now.pop();//出隊
40     }
41     ans[turn]=sum;//存儲第turn次的結果
42     return ;
43 }
44 int main(int argc, const char * argv[])
45 {
46     cin>>n>>m;
47     register int i,j;//不用register也不會T
48     char c;;
49     for(i=1;i<=n;i++)
50     {
51         for(j=1;j<=n;j++)
52         {
53             cin>>c;
54             if(c==1) matrix[i][j]=true;//存矩陣(地圖)
55         }
56     }
57     for(i=1;i<=m;i++)
58     {
59         cin>>x>>y;
60         if(!vis[x][y]) bfs(i,x,y);//如果這個點曾經沒有到過,就搜一遍
61         else ans[i]=ans[vis[x][y]];//要是曾經到過,就將曾經第幾次到的那個答案作為本次答案
62     }
63     for(i=1;i<=m;i++)
64     {
65         cout<<ans[i]<<endl;//輸出
66     }
67     return 0;
68 }
AC

P1141 01迷宮