#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 1000+10,INF=1000000; int maze[MAXN][MAXN],d[MAXN][MAXN],sign[MAXN][MAXN]; //maze为保存input的数组,d为保存每个位置表面积的数组,sign为标记数组,判断是否进行dfs int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0}; //四方向遍历的数组 int squ=0,m,n; //使用全局变量是因为很多main函数中的变量在调用函数中也需要使用。 void dfs(int x,int y) //dfs函数作用是改变原来d数组中的表面积值。从而直接在main函数中累加出结果 { sign[x][y]=0; //一开始将sign[x][y]归0,没有标记数组程序会停止工作。注: d数组减去表面积的值是依赖于周围 for(int i=0;i<4;i++) //的maze值,但是dfs在同一个位置只能执行一次。 { int nx=x+dx[i],ny=y+dy[i]; if(nx>=0&&nx<m&&ny>=0&&ny<n) //判断是否越界。 { if(maze[x][y]<=maze[nx][ny]) d[x][y]-=maze[x][y]; //如果比周围的要小,等于说那一个方向的面积全部被覆盖了。 else if(maze[x][y]>maze[nx][ny]) d[x][y]-=maze[nx][ny]; //如果比周围的要高,等于说那一个方向的面积需要去掉周围的高度值 if(sign[nx][ny]==INF) //只有未标记的maze需要dfs dfs(nx,ny); } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); for(int i=0;i<m;i++) for(int j=0;j<n;j++) scanf("%d",&maze[i][j]); for(int i=0;i<m;i++) for(int j=0;j<n;j++) { d[i][j]=4*maze[i][j]+(maze[i][j]?1:0); //初始值为maze值乘侧面积也就是4,以及顶部的一块(分0和非0讨论) sign[i][j]=INF; //标记初始全为INF } squ=0; dfs(0,0); for(int i=0;i<m;i++) for(int j=0;j<n;j++) squ+=d[i][j]; //计算剩下的表面积 printf("%d\n",squ); } return 0; }
Description
Have you ever played the video game Minecraft? This game has been one of the world‘s most popular game in recent years. The world of Minecraft is made up of lots of
blocks in a 3D map. Blocks are the basic units of structure in Minecraft, there are many types of blocks. A block can either be a clay, dirt, water, wood, air, ... or even a building material such as brick or concrete in this game.
Figure 1: A typical world in Minecraft.
Nyanko-san is one of the diehard fans of the game, what he loves most is to build monumental houses in the world of the game. One day, he found a flat ground in some place. Yes, a super flat ground without any roughness, it‘s really a lovely place to build
houses on it. Nyanko-san decided to build on a
big flat ground, so he drew a blueprint of his house, and found some building materials to build.
While everything seems goes smoothly, something wrong happened. Nyanko-san found out he had forgotten to prepare glass elements, which is a important element to decorate his house. Now Nyanko-san gives you his blueprint of house and asking for your help. Your
job is quite easy, collecting a sufficient number of the glass unit for building his house. But first, you have to calculate how many units of glass should be collected.
There are
rows and
columns on the ground, an intersection of a row and a column is a
square,and a square is a valid place for players to put blocks on. And to simplify this problem, Nynako-san‘s blueprint can be represented as an integer array
.
Which
indicates the height of his house on the square of
-th
row and -th
column. The number of glass unit that you need to collect is equal to the surface area of Nyanko-san‘s house(exclude the face adjacent to the ground).
Input
The first line contains an integer
indicating the total number of test cases.
First line of each test case is a line with two integers
.
The
lines that follow describe the array of Nyanko-san‘s blueprint, the
-th
of these lines has
integers ,
separated by a single space.
Output
For each test case, please output the number of glass units you need to collect to meet Nyanko-san‘s requirement in one line.
Sample Input
2 3 3 1 0 0 3 1 2 1 1 0 3 3 1 0 1 0 0 0 1 0 1
Sample Output
30 20
本题目一开始没有头绪,整个的思路是比较乱的,样例我是数出结果的,甚至一开始还想过直接一整面一整面地求解,显然是不现实的。
然后想到了遍历,但具体几个方向遍历也有点问题,四个方向遍历肯定是需要的,但是否要向上遍历也是个问题。后来仔细想了一下,向上遍历无非就是再加4个侧面。
可能会觉得如果加上一块在上面,被挡住的侧面不就不同了么。实际上,四方向遍历改变的状态已经包括了挡住侧面的考虑。即为高度差。
一开始停止工作了,以为是数组越界了,实际上是没有加标记导致程序不停地执行bfs函数然后自然崩了,一开始我没加标记数组是因为我觉得加了标记数组后状态无法转移
到之前经过的状态会导致缺面积。实际上还是思路不清,每遍历到一个位置,改变的表面积是从初始值经过对周围砖块的高度判定来改变自身那一方向的面积的,也就是说周围的砖块仍然要对自身判断,而且没必要对同一方向的自己判断两次。所以,标记数组是必要的。
所以啊。做题之前一定要有整体的思路,再用代码实现。而且对不可能的方法要进行排除换别的方法。
别想着边想边敲了,我这个菜鸟。