12202: 【原2202】梅西的过人
题目
题目描述
author: cloudygoose 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/2202
题目描述
梅西来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
victrid's solution
#include <iostream>
#include <stack>
#include <unordered_map>
using namespace std;
inline bool valid_messi(int** mat, int n1, int m1, int n, int m) {
return n1 < n && n1 >= 0 && m1 < m && m1 >= 0 && (mat[n1][m1] == 0 || mat[n1][m1] == 1);
}
inline bool valid_door(int** mat, int n1, int m1, int n, int m) {
return n1 < n && n1 >= 0 && m1 < m && m1 >= 0 && (mat[n1][m1] == 0 || mat[n1][m1] == 1 || mat[n1][m1] == 3);
}
bool check() {
int n, m;
cin >> n >> m;
int** inputmat = new int*[n];
for (int i = 0; i < n; i++) {
inputmat[i] = new int[m]();
for (int j = 0; j < m; j++)
cin >> inputmat[i][j];
}
stack<int> lll;
stack<int> rrr;
lll.push(0);
rrr.push(0);
while (!lll.empty()) {
int n0 = lll.top();
int m0 = rrr.top();
lll.pop();
rrr.pop();
if (n0 == n - 1 && m0 == m - 1)
return true;
if (inputmat[n0][m0] == 0) {
if (valid_messi(inputmat, n0 + 1, m0, n, m)) {
lll.push(n0 + 1);
rrr.push(m0);
}
if (valid_messi(inputmat, n0, m0 + 1, n, m)) {
lll.push(n0);
rrr.push(m0 + 1);
}
if (valid_messi(inputmat, n0, m0 - 1, n, m)) {
lll.push(n0);
rrr.push(m0 - 1);
}
if (valid_messi(inputmat, n0 - 1, m0, n, m)) {
lll.push(n0 - 1);
rrr.push(m0);
}
inputmat[n0][m0] = 2;
}
if (inputmat[n0][m0] == 1) {
inputmat[n0][m0] = 3;
}
}
lll.push(n - 1);
rrr.push(m - 1);
while (!lll.empty()) {
int n0 = lll.top();
int m0 = rrr.top();
lll.pop();
rrr.pop();
if (inputmat[n0][m0] == 3)
return true;
if (inputmat[n0][m0] == 0) {
if (valid_door(inputmat, n0 + 1, m0, n, m)) {
lll.push(n0 + 1);
rrr.push(m0);
}
if (valid_door(inputmat, n0, m0 + 1, n, m)) {
lll.push(n0);
rrr.push(m0 + 1);
}
if (valid_door(inputmat, n0, m0 - 1, n, m)) {
lll.push(n0);
rrr.push(m0 - 1);
}
if (valid_door(inputmat, n0 - 1, m0, n, m)) {
lll.push(n0 - 1);
rrr.push(m0);
}
inputmat[n0][m0] = 4;
}
if (inputmat[n0][m0] == 1) {
inputmat[n0][m0] = 5;
}
}
return false;
}
int main() {
int totalis;
int* ii = new int[totalis];
cin >> totalis;
for (int i = 0; i < totalis; i++) {
ii[i] = check();
}
for (int i = 0; i < totalis; i++) {
if (i)
cout << endl;
cout << to_string(ii[i]);
}
return 0;
}
yyong119's solution
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int movement[4][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
const int MAX_N = 1000;
struct posdata {
posdata(int a, int b, bool p) {
x = a; y = b; cross = p;
};
int x, y;
bool cross = false;
};
int a[MAX_N][MAX_N];
bool visited[MAX_N][MAX_N];
int main() {
int k; cin >> k;
while (k--) {
int n, m;
cin >> n >> m;
memset(a, 0, sizeof(a));
memset(visited, false, sizeof(visited));
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> a[i][j];
bool found = false;
queue<posdata> que; while(!que.empty()) que.pop();
que.push(posdata(0, 0, false)); visited[0][0] = true;
while (!que.empty()) {
posdata now = que.front();
for (int i = 0; i < 4; ++i) {
posdata next(now.x + movement[i][0], now.y + movement[i][1], now.cross);
if (next.x < 0 || next.x >= n || next.y < 0 || next.y >= m) continue;
if (next.x == n - 1 && next.y == m - 1) {
found = true;
break;
}
switch (a[next.x][next.y]) {
case 0:
if (!visited[next.x][next.y]) {
que.push(next);
visited[next.x][next.y] = true;
}
break;
case 1:
if (!next.cross) {
next.cross = true;
que.push(next);
visited[next.x][next.y] = true;
}
break;
}
}
if (found) break;
que.pop();
}
if (found) cout << 1 << endl; else cout << 0 << endl;
}
return 0;
}