码迷,mamicode.com
首页 > 其他好文 > 详细

VJ 122106 C-House Building

时间:2016-07-15 21:52:06      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

#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函数然后自然崩了,一开始我没加标记数组是因为我觉得加了标记数组后状态无法转移

到之前经过的状态会导致缺面积。实际上还是思路不清,每遍历到一个位置,改变的表面积是从初始值经过对周围砖块的高度判定来改变自身那一方向的面积的,也就是说周围的砖块仍然要对自身判断,而且没必要对同一方向的自己判断两次。所以,标记数组是必要的。

所以啊。做题之前一定要有整体的思路,再用代码实现。而且对不可能的方法要进行排除换别的方法。

别想着边想边敲了,我这个菜鸟。

VJ 122106 C-House Building

标签:

原文地址:http://blog.csdn.net/huangjinlv/article/details/51919047

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!