[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。。。