【上海交大oj】梅西的过人

题目描述

梅西来SJTU了!这让交大学子沸腾了,为了体现阿根廷和中国的国际友谊,校长决定让梅西与电院组织一场友谊赛。这场比赛在南体进行,把南体分成一个n乘m的矩阵,一开始梅西在(1,1)位置,球门在(n,m)位置,只要梅西能带球到球门处就算梅西胜利。电院几乎派出了所有学生来阻挡梅西,但是因为梅西的气场,他们站在场上都不敢动。 如下图,是一个3乘4的球场,每个位置上的数字表示这个位置有没有站电院的学生。m是梅西,d是球门。
m 0 1 0
0 0 1 0
1 0 1 d
同时,为了公平起见,限定梅西只能过一个人,就是说梅西能跨入“1”的格子,但只能进入一次。同时规定梅西只能四方向移动,就是说梅西不能从一个格子走到它右上角的格子。 在上面的这个例子中,梅西能通过过一个人来走到球门处。
m 1 0 0
1 1 1 1
0 0 1 d
但在这个例子中,梅西就到不了了,因为他必须过两个人。
在球场上没有时间给你思考!只有一秒钟时间在决定能否到球门处。

输入

k组数据,给出n,m,分别是矩阵的行数和列数,之后给出n行,每行m个数,每个数是0或者1,在(1,1)和(n,m)必是0。表示在这个位置上是否有电院的学生。
Sample input 1:
1
3 4
0 0 1 0
0 0 1 0
1 0 1 0

输出

输出k行,给出梅西是否能到达球门,1表示能,0表示不能。
Sample output 1:
1

数据范围:

对50%的数据  3<=N,m<=100
对100%的数据 3<=N,m<=1000,k<=4

====================================
想法很简单,就是开头结尾bfs,看看能不能找到一条公共边界,但是由于开始对广度优先的理解不够到位,很愚蠢地开了一个二维数组作为open表,结果每次查找open表中的点都要扫描一遍,结果可想而知,O(n^4)的复杂度自然过不了。然后发现了c++标准库的queue,顺利解决。代码如下(有点啰嗦,可惜不会优化):
  1 //梅西的过人 
  2 #include <iostream>
  3 #include <queue> 
  4 using namespace std;
  5 
  6 struct point {
  7     int raw;
  8     int col;
  9 };
 10 int main(){
 11     int k,n,m,i,j,q,r,c;
 12     queue<point>open;
 13 
 14     cin>>k;
 15     bool flag[k];
 16     for (i=0;i<k;++i) {
 17         cin>>n>>m;
 18         flag[i] = 0;
 19         bool map[n][m];
 20         int state[n][m]; // 0表示能到达 2表示不能到达 1表示边界 
 21         //初始化 
 22         while (open.size()>0) open.pop();
 23         for (j=0;j<n;++j)
 24             for (q=0;q<m;++q) {
 25                 cin>>map[j][q];
 26                 state[j][q]=2;
 27             }
 28         //左上角开始扫描    
 29         point point_in = {0,0};
 30         open.push(point_in);
 31         while (1) {//cout<<1;
 32             if (open.size()==0) break;
 33             point point_out = open.front();
 34             open.pop();
 35             r =point_out.raw;
 36             c = point_out.col;
 37             if (r==n-1 && c==m-1) {
 38                 flag[i] = 1;
 39                 break;
 40             }            
 41             state[r][c] = 0;
 42             if (r>0) {
 43                 if (!map[r-1][c]) {
 44                     if (state[r-1][c]==2) {
 45                         point_in.raw = r-1;
 46                         point_in.col = c;
 47                         open.push(point_in);
 48                     }
 49                     state[r-1][c] = 0;
 50                 }else state[r-1][c] = 1;
 51             }
 52             if (r<n-1) {
 53                 if (!map[r+1][c]) {
 54                     if (state[r+1][c]==2) {
 55                         point_in.raw = r+1;
 56                         point_in.col = c;
 57                         open.push(point_in);
 58                     }
 59                     state[r+1][c] = 0;
 60                 }else state[r+1][c] = 1;
 61             }    
 62             if (c>0) {
 63                 if (!map[r][c-1]) {
 64                     if (state[r][c-1]==2) {
 65                         point_in.raw = r;
 66                         point_in.col = c-1;
 67                         open.push(point_in); 
 68                     }
 69                     state[r][c-1] = 0;
 70                 }
 71                 else state[r][c-1] = 1;
 72             }                
 73             if (c<m-1) {
 74                 if (!map[r][c+1]) {
 75                     if (state[r][c+1]==2) {
 76                         point_in.raw = r;
 77                         point_in.col = c+1;
 78                         open.push(point_in);
 79                     }
 80                     state[r][c+1] = 0;
 81                 }
 82                 else state[r][c+1] = 1;
 83             }                                        
 84         }
 85         if (flag[i]) continue; //判断直接左上角是否有通道
 86         //若无,从右下角开始bfs,判断是否能到达边界 
 87         point_in.raw = n-1;
 88         point_in.col = m-1;    
 89         open.push(point_in);
 90         while (1) {
 91             if (open.size()==0) break;
 92             point point_out = open.front();
 93             r = point_out.raw;
 94             c = point_out.col;
 95             open.pop();
 96             state[r][c] = 0;
 97             if (r>0) {
 98                 if (state[r-1][c]==1) {
 99                     flag[i] = 1;
100                     break;
101                 }else if (state[r-1][c]==2) {
102                     if (!map[r-1][c]) {
103                         point_in.raw = r-1;
104                         point_in.col = c;
105                         open.push(point_in);
106                         state[r-1][c] = 0;
107                     }else state[r-1][c] = -1;
108                 }    
109             }
110             if (r<n-1) {
111                 if (state[r+1][c]==1) {
112                     flag[i] = 1;
113                     break;
114                 }else if (state[r+1][c]==2) {
115                     if (!map[r+1][c]) {
116                         point_in.raw = r+1;
117                         point_in.col = c;
118                         open.push(point_in);
119                         state[r+1][c] = 0;
120                     }else state[r+1][c] = -1;
121                 }    
122             }    
123             if (c>0) {
124                 if (state[r][c-1]==1) {
125                     flag[i]=1;
126                     break;
127                 }else if (state[r][c-1]==2) {
128                     if (!map[r][c-1]) {
129                         point_in.raw = r;
130                         point_in.col = c-1;
131                         open.push(point_in);
132                         state[r][c-1] = 0;
133                     }else state[r][c-1] = -1;
134                 }
135             }                
136             if (c<m-1) {
137                 if (state[r][c+1]==1) {
138                     flag[i]=1;
139                     break;
140                 }else if (state[r][c+1]==2) {
141                     if (!map[r][c+1]) {
142                         point_in.raw = r;
143                         point_in.col = c+1;
144                         state[r][c+1] = 0;
145                     }    
146                 }else state[r-1][c+1] = -1;
147             }                                
148         } 
149     } 
150     for (i=0;i<k;++i) {
151         if (flag[i]) cout<<1<<endl; 
152         else cout<<0<<endl;
153     }
154     return 0;
155 }


原文地址:https://www.cnblogs.com/wenma/p/4474722.html