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

时间: 2024-08-25 17:07:44

POJ 2329 -- Nearest number - 2的相关文章

[NewTrain 10][poj 2329]Nearest Number - 2

题面: http://poj.org/problem?id=2329 题解: 这题有很多做法 1. 搜索 复杂度$O(n^4)$ 但是实际上远远达不到这个复杂度 所以可以通过 2. 对于每一个格子,我们枚举每一行,找到每一行离他最近的格子 当前格子向右移动时,每一行离他最近的格子不可能向左移动,所以复杂度$O(n^3)$ 3. dp 一共四个方向 左上到右下 左下到右上 右上到左下 右下到左上 然后分别dp 找到这个方向离他最近的格子 以左上到右下为例 $f[i][j]$可由$f[i-1][j]

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 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 pro

POJ 1330 Nearest Common Ancestors(树)

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17628   Accepted: 9335 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

[POJ 1330] Nearest Common Ancestors (朴素方法)

POJ 1330: Nearest Common Ancestors Time Limit: 1000ms Memory Limit: 32Mb Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer fro

POJ - 1330 Nearest Common Ancestors(基础LCA)

POJ - 1330 Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %lld & %llu Submit Status Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In t

POJ 1330 Nearest Common Ancestors 倍增算法的LCA

POJ 1330 Nearest Common Ancestors 题意:最近公共祖先的裸题 思路:LCA和ST我们已经很熟悉了,但是这里的f[i][j]却有相似却又不同的含义.f[i][j]表示i节点的第2j个父亲是多少   这个代码不是我的,转自 邝斌博客 1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-9-5 9:45:17 4 File Name :F

POJ 1330 Nearest Common Ancestors LCA题解

本题是一个多叉树,然后求两点的最近公共单亲节点. 就是典型的LCA问题.这是一个很多解法的,而且被研究的很透彻的问题. 原始的解法:从根节点往下搜索,若果搜索到两个节点分别在一个节点的两边,那么这个点就是最近公共单亲节点了. Trajan离线算法:首次找到两个节点的时候,如果记录了他们的最低单亲节点,那么答案就是这个最低的单亲节点了. 问题是如何有效记录这个最低单亲节点,并有效根据遍历的情况更新,这就是利用Union Find(并查集)记录已经找到的节点,并及时更新最新访问的节点的当前最低单亲节

POJ 1330 Nearest Common Ancestors LCA(在线RMQ,离线Tarjan)

链接:http://poj.org/problem?id=1330 题意:只看题目就知道题目是什么意思了,最近公共祖先,求在一棵树上两个节点的最近公共祖先. 思路:求最近公共祖先有两种算法,在线和离线,在线方法是用RMQ求LCA,一句话总结就是在从DFS时,从第一个点到第二个点的最短路径中深度最浅的点就是公共祖先,用RMQ处理,一般问题的最优解决方式的复杂度是O(NlogN)的预处理+N*O(1)的查询.离线方法是Tarjan算法,将所有询问的两个点都记录下来,在DFS过程中不断将每个点自身作为

poj 2104 K-th Number(划分树模板)

划分树模板题,敲上模板就ok了. #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define MP