zoukankan      html  css  js  c++  java
  • [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行,每行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('
    ');
    	}
    	
    	return 0;
    }
    

    最后要多输出一个空格。。。

    当然这题可以从所有 1 的位置出发 BFS。。。

  • 相关阅读:
    java中需要注意的小细节
    利用mysql查询总数据条数,再php处理数据转出数组,生成随机返回到页面,可以做成刷新页面,出现不同的内容
    js刷新页面方法大全
    CSS3自定义滚动条样式 -webkit-scrollbar(转)
    使用jquery.qrcode生成二维码(转)
    JS鼠标事件大全 推荐收藏
    微信小程序
    js几种生成随机颜色方法
    Canvas——使用定时器模拟动态加载动画!
    H5——表单验证新特性,注册模态框!
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6525038.html
Copyright © 2011-2022 走看看