[BZOJ2252][2010Beijing wc]矩阵距离
[BZOJ2252][2010Beijing wc]矩阵距离
试题描述
假设我们有矩阵,其元素值非零即1
a11…… a1m
…………….
an1…….anm
定义aij与akl之间的距离为D(aij,akl)=abs(i-k)+abs(j-L)
输入
输入文件的第一行为两个整数,分别代表n和m。
接下来的n行,第i行的第 j个字符代表aij
接下来的n行,第i行的第 j个字符代表aij
输出
输出包含N行,每行M个用空格分开的数字,其中第i行第J个数字代表
Min(D(aij,axy) 1<=x<=N 1<=y<=m,且axy=1
输入示例
3 4 0001 0011 0110
输出示例
3 2 1 0 2 1 0 0 1 0 0 1
数据规模及约定
对于100%的数据,满足 0 < m n <=1000
题解
这道题的弱化弱化版。。。弱化到没什么相似之处。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
using namespace std;
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxn 1010
#define oo 2147483647
int n, m, dis[maxn][maxn], f[maxn][maxn], g[maxn][maxn];
bool Map[maxn][maxn];
int main() {
n = read(); m = read();
for(int i = 1; i <= n; i++) {
char c = getchar();
while(!isdigit(c)) c = getchar();
int j = 0;
while(isdigit(c)) Map[i][++j] = c - '0', c = getchar();
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) dis[i][j] = oo;
for(int j = 1; j <= m; j++)
if(Map[i][j]) dis[i][j] = 0;
else if(j > 1 && dis[i][j-1] < oo) dis[i][j] = dis[i][j-1] + 1;
for(int j = m; j; j--)
if(Map[i][j]) dis[i][j] = 0;
else if(j < m && dis[i][j+1] < oo) dis[i][j] = min(dis[i][j], dis[i][j+1] + 1);
}
for(int j = 1; j <= m; j++) {
int mn = oo;
for(int i = 1; i <= n; i++) {
if(dis[i][j] < oo) mn = min(mn, dis[i][j] - i);
f[i][j] = mn < oo ? mn + i : oo;
}
for(int i = 1; i <= (n >> 1); i++) swap(dis[i][j], dis[n-i+1][j]);
mn = oo;
for(int i = 1; i <= n; i++) {
if(dis[i][j] < oo) mn = min(mn, dis[i][j] - i);
g[i][j] = mn < oo ? mn + i : oo;
}
for(int i = 1; i <= n; i++) f[i][j] = min(f[i][j], g[n-i+1][j]);
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) printf("%d ", f[i][j] < oo ? f[i][j] : -1);
putchar('\n');
}
return 0;
}
最后要多输出一个空格。。。
当然这题可以从所有 1 的位置出发 BFS。。。

浙公网安备 33010602011771号