【上海交大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 }

 



你可能感兴趣的:(OJ)