Nearest number - 2
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 4232 | Accepted: 1311 |
Description
Input is the matrix A of N by N non-negative integers.
A distance between two elements Aij and Apq is defined as |i − p| + |j − q|.
Your program must replace each zero element in the matrix with the nearest non-zero one. If there are two or more nearest non-zeroes, the zero must be left in place.
Constraints
1 ≤ N ≤ 200, 0 ≤ Ai ≤ 1000000
A distance between two elements Aij and Apq is defined as |i − p| + |j − q|.
Your program must replace each zero element in the matrix with the nearest non-zero one. If there are two or more nearest non-zeroes, the zero must be left in place.
Constraints
1 ≤ N ≤ 200, 0 ≤ Ai ≤ 1000000
Input
Input contains the number N followed by N2 integers, representing the matrix row-by-row.
Output
Output must contain N2 integers, representing the modified matrix row-by-row.
Sample Input
3
0 0 0
1 0 2
0 3 0
Sample Output
1 0 2
1 0 2
0 3 0
Source
Northeastern Europe 2003, Far-Eastern Subregion
题目大意:有一个N*N方阵,将其中的0替换为曼哈顿距离最近的非零元素的值;若有多余1个的最近非零元素,则维持原值0不变。
解题思路:
这题用动规没思路啊,看了网上的代码,很神奇,怎么说,思路很容易懂,但是代码实现我不行
两遍扫描,分别考虑来自左上和右下的元素,dp数组记录距离该元素最近的非零元素的个数、距离和位置。注意dp数组的更新规则。
AC代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stdlib.h>
#include <math.h>
using namespace std;
#define MAXN 203
#define INF 100000000
struct DPNode{
int count;
int dis;
int x;
int y;
};
int n;
int mat[MAXN][MAXN];
DPNode dp[MAXN][MAXN];
int dir[][2] = { { 0, -1 }, { 1, 0 }, { -1, 0 }, { 0, 1 } };
void UL(int i, int j)
{
if (i > 0)//L
{
if (dp[i][j].dis > dp[i - 1][j].dis + 1)
{
dp[i][j].dis = dp[i - 1][j].dis + 1;
dp[i][j].count = dp[i - 1][j].count;
dp[i][j].x = dp[i - 1][j].x;
dp[i][j].y = dp[i - 1][j].y;
}
else if (dp[i][j].dis == dp[i - 1][j].dis + 1)
{
if (!(dp[i][j].x == dp[i - 1][j].x&&dp[i][j].y == dp[i - 1][j].y
&&dp[i][j].count == 1 && dp[i - 1][j].count == 1))//确保两个点不是同一点
dp[i][j].count += dp[i - 1][j].count;
}
}
if (j > 0)//U
{
if (dp[i][j].dis > dp[i][j - 1].dis + 1)
{
dp[i][j].dis = dp[i][j - 1].dis + 1;
dp[i][j].count = dp[i][j - 1].count;
dp[i][j].x = dp[i][j - 1].x;
dp[i][j].y = dp[i][j - 1].y;
}
else if (dp[i][j].dis == dp[i][j - 1].dis + 1)
{
if (!(dp[i][j].x == dp[i][j - 1].x&&dp[i][j].y == dp[i][j - 1].y
&&dp[i][j].count == 1 && dp[i][j - 1].count == 1))
dp[i][j].count += dp[i][j - 1].count;
}
}
}
void DR(int i, int j)
{
if (i < n - 1)//R
{
if (dp[i][j].dis > dp[i + 1][j].dis + 1)
{
dp[i][j].dis = dp[i + 1][j].dis + 1;
dp[i][j].count = dp[i + 1][j].count;
dp[i][j].x = dp[i + 1][j].x;
dp[i][j].y = dp[i + 1][j].y;
}
else if (dp[i][j].dis == dp[i + 1][j].dis + 1)
{
if (!(dp[i][j].x == dp[i + 1][j].x&&dp[i][j].y == dp[i + 1][j].y
&&dp[i][j].count == 1 && dp[i + 1][j].count == 1))
dp[i][j].count += dp[i + 1][j].count;
}
}
if (j < n - 1)//D
{
if (dp[i][j].dis > dp[i][j + 1].dis + 1)
{
dp[i][j].dis = dp[i][j + 1].dis + 1;
dp[i][j].count = dp[i][j + 1].count;
dp[i][j].x = dp[i][j + 1].x;
dp[i][j].y = dp[i][j + 1].y;
}
else if (dp[i][j].dis == dp[i][j + 1].dis + 1)
{
if (!(dp[i][j].x == dp[i][j + 1].x&&dp[i][j].y == dp[i][j + 1].y
&&dp[i][j].count == 1 && dp[i][j + 1].count == 1))
dp[i][j].count += dp[i][j + 1].count;
}
}
}
int main()
{
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &mat[i][j]);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dp[i][j].dis = INF;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (mat[i][j]>0)
{
dp[i][j].dis = 0;
dp[i][j].count = 1;
dp[i][j].x = i;
dp[i][j].y = j;
}
else
{
UL(i, j);
}
}
}
for (int i = n - 1; i >= 0; i--)
{
for (int j = n - 1; j >= 0; j--)
{
if (mat[i][j] == 0)
{
DR(i, j);
}
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n-1; j++)
{
printf("%d ", dp[i][j].count == 1 ? mat[dp[i][j].x][dp[i][j].y] : 0);
}
printf("%d\n", dp[i][n - 1].count == 1 ? mat[dp[i][n - 1].x][dp[i][n - 1].y] : 0);
}
}
return 0;
}