Codeforces 0. 2020面试题
原题链接
中等
作者:
孤独时代的罗永浩
,
2020-09-05 12:11:35
,
所有人可见
,
阅读 506
给定一个n * m 的矩阵,矩阵元素为0 或者 1,保证左上角和右下角元素均为1, 现在你可以从左上角出发沿上下左右四个方向向右下角前进,如果遇到0,就需要将 0 转换成为 1,请问最少需要转换多少个0才可以到达终点。
输入样例
4 5
1 0 0 0 0
1 0 1 1 1
1 0 1 0 1
1 1 1 0 1
注意:可能还有蛇皮路线,代码是自己写的可能有错误
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1000;
int n, m, ans;
int g[N][N];
bool st[N][N];
void bfs(int x, int y)
{
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
queue<pair<int, int>> ones;
queue<pair<int, int>> zeros;
if(g[x][y] == 0) zeros.push({x, y});
else ones.push({x, y});
st[x][y] = true;
while(zeros.size() || ones.size())
{
if(ones.size())
{
auto cur = ones.front();
ones.pop();
if(cur.first == n && cur.second == m) return;
for(int i = 0; i < 4; i++)
{
int nx = cur.first + dx[i], ny = cur.second + dy[i];
if(nx <= 0 || ny <= 0 || nx > n || ny > m) continue;
if(st[nx][ny] == true) continue;
st[nx][ny] = true;
if(g[nx][ny] == 1) ones.push({nx, ny});
else zeros.push({nx, ny});
}
}
else
{
ans++;
int s = zeros.size();
for(int i = 0; i < s; i++)
{
auto cur = zeros.front();
zeros.pop();
for(int j = 0; j < 4; j++)
{
int nx = cur.first + dx[j], ny = cur.second + dy[j];
if(nx <= 0 || ny <= 0 || nx > n || ny > m) continue;
if(st[nx][ny] == true) continue;
st[nx][ny] = true;
if(g[nx][ny] == 1) ones.push({nx, ny});
else zeros.push({nx, ny});
}
}
}
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> g[i][j];
bfs(1, 1);
cout << ans << endl;
return 0;
}
类似于 https://www.acwing.com/blog/content/173/
增加了一些操作的DFS
我觉得更像是双端bfs
哦 我感觉思路挺像的。
我看那题目写到
“另外, 你可以花费 2个金币施展魔法让下一个无色格子暂时变为你指定的颜色。
balbalabala xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?”