首页 > 代码库 > POJ 2329 -- Nearest number - 2

POJ 2329 -- Nearest number - 2

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 4224   Accepted: 1308

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

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
 
思路:最好想的当然就是暴力搜索,但是仍然有几个小细节需要注意:
  1. 确认范围:以目标点为中心(即菱形对角线交点),向外画菱形。菱形边上的点即为此轮需要搜索的点。菱形由小到大。

技术分享 如左图,O点是目标点,菱形的四个顶点坐标的变化记录在cx、cy数组中。

        2.找规律:四条边在计算中i,j的变化是不同的,储存在dx、dy数组中。注意c、d两数组要对应上。

        3.注意特殊情况:

  • n=1的,直接输出;
  • 当前目标点本来就大于零的,直接输出;
  • 菱形全部出界的,目标点仍为零。

 

最后吐槽一下这道题真是太乱了,本蒟蒻硬是调了一晚上的程序才调出来_〆(′Д` )…… 

技术分享
 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 using namespace std;
 8 int n;
 9 int map[210][210];
10 int cx[5]={-1,0,1,0},cy[5]={0,-1,0,1};   //菱形的四个顶点 
11 int dx[5]={1,1,-1,-1},dy[5]={-1,1,1,-1};  //菱形四条边上每个点的坐标变化 
12 bool edge(int x,int y)  //判断边界 
13 {
14     if(x<=0 || x>n || y<=0 ||y>n) return false;
15     return true;
16 }
17 void bfs(int a,int b,int k)
18 {
19     if(k>n) {printf("0 ");return ;}  //菱形已全部出界但仍未找到 >0的 ,本身仍为零 
20     int cnt=0,tmpx,tmpy;
21     bool ok=false;
22     for(int i=0;i<4;i++)  //菱形的四条边
23     {
24         int xx=a+k*cx[i],yy=b+k*cy[i];
25         for(int j=0;j<k;j++)  //每条边分别找 
26         {
27             if(map[xx][yy]>0 && edge(xx,yy))  //找到未出界的 >0的数 
28             {
29                 if(cnt==1) {printf("0 ");ok=true;break;}  //之前已经找到过一个,这个是第二个,因此仍为零 (同时这一圈后面的也不用再考虑了) 
30                 cnt++;
31                 tmpx=xx;tmpy=yy;  //记录非零数坐标,如果 cnt一直是 1的话输出用 
32             }
33             xx+=dx[i];   //按不同边的特点更新圈上的坐标 
34             yy+=dy[i];
35         }
36         if(ok) break;  //已找到 >1个 cnt 
37     }
38     if(cnt==0) bfs(a,b,k+1);  //这一圈上一个大于零的数都没有 
39     else if(!ok) printf("%d ",map[tmpx][tmpy]);  //只找到一个 cnt,输出找到的非零数 
40 }
41 
42 int main()
43 {
44     scanf("%d",&n);
45     for(int i=1;i<=n;i++)
46         for(int j=1;j<=n;j++) scanf("%d",&map[i][j]);
47     for(int i=1;i<=n;i++)
48     {
49         for(int j=1;j<=n;j++)
50         {
51             if(map[i][j]>0) {printf("%d ",map[i][j]);continue;}  //本身大于零无需变化 
52             bfs(i,j,1);
53         }
54         printf("\n");
55     }
56     //system("pause");
57     return 0;
58 }
POJ 2329

 

POJ 2329 -- Nearest number - 2