标签:
梅西来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 }
标签:
原文地址:http://www.cnblogs.com/wenma/p/4474722.html