이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

쌓여있는 상자들의 겉넓이.

n*n 크기의 바닥에 각 변의 길이가 1인 상자들을 바닥이 보이지 않게 쌓았을 때, 상자들의 겉넓이의 합은? (단, 바닥에는 길이 1마다 눈금이 그려져 있으며, 상자는 눈금에 맞추어 쌓는다.)

추가: 겉넓이에는 바닥을 포함합니다.

입력 예: [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]

입력 예에서 각 숫자는 해당 칸에 쌓인 상자의 개수이다.

출력: 120

2016/04/13 21:46

Flair Sizz

+1 문제가 도저히 이해가 안갑니다. - 상파, 2016/04/20 00:17
n*n 크기의 칸에 상자를 쌓았을 때 겉으로 드러나는 넓이를 뜻합니다. - Flair Sizz, 2016/04/21 13:05
음.. >.< 입력 예 [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]] 는 그럼 무엇을 뜻하는 것인가요? - 상파, 2016/04/22 22:09
[1,4,3,4] [2,3,4,1] [3,4,2,1] [9,3,2,1] 상파님 아마 이렇게 4X4크기를 나타내는것 같구 각 1X1들은 상자의 높이 인거 같네요.. 저도 한참 생각했습니다 ㅎㅎ.. - 이 우람, 2016/04/23 16:55
아 그게 문제였군요. 수정하겠습니다. - Flair Sizz, 2016/04/23 21:22

29개의 풀이가 있습니다.

어렵겠다..라고 생각했는데 의외로 쉽게 풀리네요. 쌓여있는 상자들의 맨 아래 층부터 겉으로 드러난 옆면의 개수를 세고 위층으로 올라갑니다. 두 번째 층에서부터는 같은 식으로 옆면의 개수를 세면서 위로 드러난 면의 개수도 추가로 더합니다.

이를 위해서 2차원 배열의 각 값이 0보다 크면 상자가 있는 칸, 그렇지 않으면 상자가 없는 칸으로 간주하고 한 층의 옆/윗면을 다 세고 나면 모든 칸의 값을 1씩 빼고 위층으로 올라갑니다. 이 때 각 옆면이 겉면인지는 그 옆에 상자가 없으면 되는거죠.

다만, "쌓여있는 상자의 겉넓이"에서 바닥면의 면적을 더하는게 맞는지는 애매하네요.


def main(data):
    width = len(data[0])
    height = len(data)
    boxes = [[0] * width] * height

    for i, line in enumerate(data):
        boxes[i] = line

    level = 1
    result = 0

    def check_boxes():
        for story in boxes:
            if any([x >= 0 for x in story]):
                return True
        return False

    # 바닥개수 세기
    result += sum([sum([1 for y in x if y > 0]) for x in boxes])

    while check_boxes():
        sides = 0
        ups = 0
        for x in range(width):
            for y in range(height):
                if boxes[x][y] > 0: # 옆면의 개수 세기
                    if y == 0 or boxes[x][y-1] < 1:
                        sides += 1
                    if y == height - 1 or boxes[x][y+1] < 1:
                        sides += 1
                    if x == 0 or boxes[x-1][y] < 1:
                        sides += 1
                    if x == width - 1 or boxes[x+1][y] < 1:
                        sides += 1
        if level > 1: # 위로 드러난 면의 개수 세기
            ups = sum([sum([1 for y in x if y == 0]) for x in boxes])
        result += sides + ups
        level += 1
        boxes = [[y -1 for y in x] for x in boxes]
    return result

2016/04/20 10:21

룰루랄라

바닥면 더하는 것으로 수정하겠습니다. - Flair Sizz, 2016/04/21 13:00

쌓여있는 상자더미를 위에서 바라봤을 때 각각의 칸으로 나눠서 옆넓이를 하나씩 하나씩 게산했습니다.

각 칸에서 그 칸 옆쪽에 상자가 원래칸보다 낮게 쌓여있을 경우, 두 높이의 차이가 그 쪽방향의 옆넓이입니다.
각 칸에서 그 칸 옆쪽에 상자가 원래칸보다 높게 쌓여있을 경우, 옆넓이는 0입니다.
각 칸에서 옆칸과의 차를 계산해서 양수이면 더해주고 음수이면 더해주지 않습니다.
옆칸이 상자가 쌓여있지 않은 바깥쪽이면 그냥 상자 높이가 그 쪽 옆면의 넓이입니다.

python 2.7

#-*- coding: utf-8 -*-
h = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
res = 0
n = len(h)
m = len(h[0])
for i in range(n):
    for j in range(m):
        res += 2 # 상자더미의 맨 윗면과 맨 아랫면
        for (x,y) in [(0,1),(0,-1),(-1,0),(1,0)]:
            if i+x in range(n) and j+y in range(m):
                temp = h[i][j] - h[i+x][j+y]
                res += temp if temp > 0 else 0
            else :
                res += h[i][j]
print res

2016/04/23 21:43

상파

in 구문에서 iterable 쓸 수 있는 걸 오늘 처음 알았네요. 배워갑니다. - Flair Sizz, 2016/04/23 23:28
sample = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]

area_calc = lambda arr: sum((0 if arr[i] - arr[i-1]<0 else arr[i] - arr[i-1]) if i else arr[i] for i in range(len(arr)))

n = len(sample)
r = 2*( n*n + sum(area_calc(i) for i in sample) + sum(area_calc(j) for j in zip(*sample)) )
print(r)

[1,4,3,4] 로 쌓여 있는 행의 옆면의 면적은
1 + (4-1) + 3-4 + (4-3) = 1 + 3 + 0 + 1 = 5
대칭면은 면적이 같으므로 삼면의 면적을 합 한 뒤 2배

2018/07/24 17:10

Creator

sample = [[1,4,3,4],[2,3,4,1],[3,4,2,1],[9,3,2,1]]
class cube():
    def __init__(self, co_3):
        self.co_3 = co_3
        self.faceList = {'px':None,'nx':None,'py':None,'ny':None,'pz':None,'nz':None}
    def surface(self):
        result = 0
        for x in self.faceList.keys():
            if self.faceList[x] == None:
                result += 1
        return result

class space():
    def __init__(self, n):
        self.n = n
        self.cubemap = []
        self.newFloor('cube')
    def newFloor(self, fill = None):
        if fill == 'cube':
            self.cubemap.append(list(list(cube((0,y,x)) for x in range(self.n)) for y in range(self.n)))
        else:
            self.cubemap.append(list(list(None for x in range(self.n)) for y in range(self.n)))
    def addCube(self, co_2):
        y, x = co_2
        if self.cubemap[-1][y][x] != None:
            self.newFloor()
            self.cubemap[-1][y][x] = cube((len(self.cubemap)-1,y,x))
        else:
            for z in range(len(self.cubemap)):
                if self.cubemap[z][y][x] == None:
                    self.cubemap[z][y][x] = cube((z, y, x))
                    break
    def refresh(self, co_3):
        z, y, x = co_3
        c = self.cubemap
        #'px'
        if x < self.n-1 and type(c[z][y][x+1]) == cube:
            c[z][y][x+1].faceList['px'] = 1
        #'py'
        if y < self.n-1 and type(c[z][y+1][x]) == cube:
            c[z][y+1][x].faceList['py'] = 1
        #'pz'
        if z < len(c)-1 and type(c[z+1][y][x]) == cube:
            c[z+1][y][x].faceList['pz'] = 1
        #'nx'
        if type(c[z][y][x-1]) == cube and x > 0:
            c[z][y][x-1].faceList['nx'] = 1
        #'ny'
        if type(c[z][y-1][x]) == cube and y > 0:
            c[z][y-1][x].faceList['ny'] = 1
        #'nz'
        if type(c[z-1][y][x]) == cube and z > 0:
            c[z-1][y][x].faceList['nz'] = 1
    def cal(self):
        result = 0
        for z in self.cubemap:
            for y in z:
                for x in y:
                    if x != None:
                        self.refresh(x.co_3)
        for z in self.cubemap:
            for y in z:
                for x in y:
                    if x != None:
                        result += x.surface()
        return result

if __name__ == '__main__':
    sp = space(len(sample))
    for y, i in enumerate(sample):
        for x, j in enumerate(i):
            for k in range(j-1):
                sp.addCube((y, x))
    print(sp.cal())

파이썬 3.5.1

2016/04/13 21:52

Flair Sizz

요즘 선형대수학을 공부중이어서 행렬의 개념으로 생각해봤습니다.

윗면 아랫면은 n제곱으로 구할 수 있으니 쉽고

전후좌우 면을 구해야 하는데요. 좀 생각해보면 '전후'와 '좌우'는 각각 겉넓이가 같습니다. 앞과 뒤에서 정면으로 물체를 바라본다 생각하면 보이는 모양이 (좌우 반전 정도는 있어도) 같지요. 그런 원리입니다.

그럼 전후 좌우는 어떻게 구하는지 생각을 좀 해봤는데요.

주어진 리스트를 행렬처럼 쓴다고 생각해보죠.(행렬을 표현하는 방법은 리스트의 리스트, 딕셔너리 등이 있지만 여기선 리스트로 구현)

X = [[1, 4, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [9, 3, 2, 1]]

여기서 각 행들의 겉넓이를 구하고, 이 행 겉넓이의 합을 구하면 이것은 "그 방향에서 바라봤을 때의 겉넓이"가 됩니다.

즉 전후면 전후 방향의 겉넓이, 좌우면 좌우방향의 겉넓이가 되는거죠.

편의상 앞뒤를 구했다 생각하겠습니다.

그럼 좌우를 구해야죠? 좌우 방향은 주어진 행렬의 열과 행을 바꾸고(선형대수학에서는 transpose라고 합니다.)

다시 같은 방법으로 행들의 겉넓이를 구하면 됩니다.

결국 총 겉넓이는 위아래+앞뒤+좌우 겉넓이를 합치면 됩니다.

이러한 원리로 구현한 파이썬 코드입니다.

X = [[1, 4, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [9, 3, 2, 1]]


def row_area(row_list):
    """각 row 의 겉넓이를 구하는 함수"""

    area0 = row_list[0]

    for j in range(len(row_list)-1):

        if row_list[j] < row_list[j+1]:
            area0 += (row_list[j+1]-row_list[j])
        else:
            pass

    return area0


def sum_row(matrix_list):
    """row_area 에서 구한 각 row의 겉넓이를 합치는 함수 """
    return sum(row_area(matrix_list[i]) for i in range(len(matrix_list)))

def transpose(matrix_x):
    """column area를 구하기 위해 matrix의 row와 column을 바꾸는 함수

    column_area는 matrix를 transpose 한 후 row_area를 구하는 과정으로 이루어진다.
    """
    matrix_y = [[0 for j in range(len(matrix_x[0]))] for i in range(len(matrix_x))]
    for i in range(len(matrix_x)):
        for j in range(len(matrix_x[0])):
            matrix_y[i][j] = matrix_x[j][i]

    return matrix_y

Y = transpose(X)

row_area_X = sum_row(X)
col_area_X = sum_row(Y)
floor_ceiling = len(X)**2

Total_area = 2*(row_area_X+col_area_X+floor_ceiling)

print(Total_area)

2016/04/24 15:33

Song YC

처음에는 보이는 면에 대해서만 계산을 하다보니 음영지역(?) 에 대한 계산이 어렵더군요.. 각 상자의 수에대해서 차이를 구하고 양수일 경우는 보이지 않는 부분 / 음수일 경우 보이는 부분으로 계산

    private int gen2(Integer[][] xx) {
        int area, tmp, sum = 0;
        for (Integer[] x : xx) {
            area = 0;
            for (int i = 0; i < x.length; i++) {
                tmp = (i == 0 ? -x[i] : x[i - 1] - x[i]);
                area += tmp > 0 ? 0 : tmp;
            }
            sum += Math.abs(area);
        }
        int upAndDown = (int) Math.pow(xx.length, 2) * 2;
        return sum*4 + upAndDown;
    }

2016/05/04 16:51

Lee Brandon

Ruby

gap = ->a { a.flat_map {|e| [0,*e,0].each_cons(2).map {|a,b|(b-a).abs} } }
area = ->a { gap[a+a.transpose].sum + (a.size**2)*2 }

Test

expect( area[ [[1,2],
               [2,4]] ]).to eq 32
expect( area[ [[1,4,3,4],
               [2,3,4,1],
               [3,4,2,1],
               [9,3,2,1]]] ).to eq 120

Output

#=> puts area[ [[1,4,3,4],[2,3,4,1],[3,4,2,1],[9,3,2,1]] ]
120

2016/05/04 19:01

rk

data = [[0,0,0,0,0,0],
        [0,1,4,3,4,0],
        [0,2,3,4,1,0],
        [0,3,4,2,1,0],
        [0,9,3,2,1,0],
        [0,0,0,0,0,0]]


direction = [[-1,0],
             [1,0],
             [0,-1],
             [0,1]]

sum_area=0
for i in range(1,len(data)-1):
    for j in range(1,len(data[i])-1):
        for d in direction:
            di=d[0]
            dj=d[1]
            if data[i][j] > data[i+di][j+dj]:
                sum_area=sum_area + data[i][j] - data[i+di][j+dj]
        sum_area=sum_area+2
        print(sum_area)

print(sum_area)

파이썬 3입니다. 밑면 포함되는지 모르고 왜 답이 이상하게나오지 엄청 헤맸네요-_-ㅋㅋ 걍 단순하게 풀었습니다. 예외처리가 귀찮아서 배열을 0으로 둘러싸버렸네요..

2016/05/07 15:24

김 매미

 static void Main(string[] args)
        {
            int[] rectangls = new int[] { 1, 4, 3 ,4,2,3,4,1,3,4,2,1,9,3,2,1};
            int max = 0;
            foreach (int rect in rectangls)
            {
                if (max < rect)
                {
                    max = rect;
                }
            }
            string[,] rectdraw = new string[rectangls.Length, max];
            for (int i = 0; i < rectangls.Length; i++)
            {
                for (int x = 0; x < max; x++)
                {
                    rectdraw[i, max - x - 1] = "■";
                }
                for (int z = rectangls[i]; z < max; z++)
                {
                    rectdraw[i, max - z - 1] = "□";
                }
            }
            for (int y = 0; y < max; y++)
            {
                for (int x = 0; x < rectangls.Length; x++)
                {

                    Console.Write(rectdraw[x, y]);
                }
                Console.WriteLine();
            }
            int topbottom = rectangls.Length * 2;
            int side = 0;
            for (int i = 0; i < rectangls.Length; i++)
            {
                if (i == 0)
                {
                    side += rectangls[i];
                }
                if (i < rectangls.Length - 1)
                    side += Math.Abs(rectangls[i] - rectangls[i + 1]);
                if (i == rectangls.Length - 1)
                {
                    side += rectangls[i];
                }
            }
            Console.WriteLine(topbottom + side);
        }

2016/05/08 19:25

정우진

>>> l = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
>>> l + zip(*l)
[[1, 4, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [9, 3, 2, 1], (1, 2, 3, 9), (4, 3, 4, 3), (3, 4, 2, 2), (4, 1, 1, 1)]
>>> inner = lambda l: sum(abs(x - y) for ll in l + zip(*l) for x, y in zip(ll, ll[1:]))
>>> inner(l)
39
>>> outer = lambda l: sum(x[0] + x[-1] for x in l + zip(*l))
>>> outer(l)
49
>>> flatten_metrix = [cell for cells in l for cell in cells]
>>> top_bottom_cnt = len(flatten_metrix) * 2 - flatten_metrix.count(0)
>>> inner(l) + outer(l) + top_bottom_cnt
120

2016/05/11 21:15

Park Ohyoung

안녕하세요. c++로 풀어봤습니다. 동서남북 네방향에서 반대방향으로 진행하면서 볼 수 있는 면들을 전부 더했습니다.

#include<iostream>

using namespace std;
void main()
{
    cout<<"Hello Stranger!!"<<endl;

    int input[4][4] =  {{1,4,3,4}, {2,3,4,1}, {3,4,2,1}, {9,3,2,1}};
    int res = 0;

    for(int i=0; i<4; i++)
    {
        int tmp1 = 0;
        int tmp2 = 0;

        for(int j=0; j<4; j++)
        {
            if( tmp1 < input[i][j] )
                res += input[i][j] - tmp1;

            tmp1 = input[i][j];

            if( tmp2 < input[j][i] )
                res += input[j][i] - tmp2;

            tmp2 = input[j][i];

            res++;
        }
        cout<<" : "<<res<<endl;
    }

    for(int i=3; i>=0; i--)
    {
        int tmp1 = 0;
        int tmp2 = 0;

        for(int j=3; j>=0; j--)
        {
            if( tmp1 < input[i][j] )
                res += input[i][j] - tmp1;

            tmp1 = input[i][j];

            if( tmp2 < input[j][i] )
                res += input[j][i] - tmp2;

            tmp2 = input[j][i];

            res++;
        }
    }

    cout<<res;

}

2016/11/09 22:55

이재웅

def do(src):
    a = sum([len(x) for x in src]) * 2 # 위, 아래
    b = sum([abs(x[i-1] - x[i]) for x in src
                                for i in range(1, len(x))]) # 가로 줄 차이
    c = sum([abs(src[i - 1][x] -  src[i][x])
                             for x in range(len(src))
                             for i in range(1, len(src))]) # 세로 줄 차이
    d = sum(src[0]) \
        + sum(src[len(src) - 1]) \
        + sum([src[x][0] + src[x][len(src[x]) - 1] for x in range(len(src))]) # 사방 걷면

    print(a + b + c + d)


do([[1,4,3,4],
    [2,3,4,1],
    [3,4,2,1],
    [9,3,2,1]])

Python 3.5.2에서 작성 하였습니다.

2016/12/14 09:53

Yeo HyungGoo

package sss;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

/*
 * n*n 크기의 바닥에 각 변의 길이가 1인 상자들을 바닥이 보이지 않게 쌓았을 때, 상자들의 겉넓이의 합은?
 * (단, 바닥에는 길이 1마다 눈금이 그려져 있으며, 상자는 눈금에 맞추어 쌓는다.)
 * 입력 예: [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
 * ->   [1,4,3,4]
    [2,3,4,1]
    [3,4,2,1] 
    [9,3,2,1]  이렇게 n*n을 표현하고 각 숫자는 높이를 의미한다. 

    1. 윗 + 아랫면 넓이 구하기(전체 n * 2)
    2. 옆면 겹치는 면 무시하고 구하기 (전체 갯수 * 4)
    3. 같은 행끼리 겹치는 면 빼기(a[i],a[i+1]비교후 작은거 * 2 빼기)
    4. 같은 열끼리 겹치는 면 빼기(a[i],a[i+n]비교후 작은거 * 2 빼기)
 */
public class Surface_Area {

    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String state = reader.readLine();
            ArrayList<Integer> state_split = new ArrayList<Integer>();
            StringTokenizer token = new StringTokenizer(state,"\\[|\\]|[,]|[ ]");
            for(int i = 0; token.hasMoreTokens(); i++)
                state_split.add(Integer.parseInt(token.nextToken()));
            int n = (int) Math.sqrt(state_split.size());

            int surface_area = surface(state_split, n);
            System.out.println(surface_area);

        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    static int surface(ArrayList<Integer> state_split, int n){
        int area = 0;
        int size = state_split.size();
        int temp = 0;
        //1.
        area += 2*size;
        //2.
        for(int i = 0; i < size;i++)
            area+=state_split.get(i)*4;
        //3.
        for(int i = 0, j = 0;i < size;i+=4){
            for(j = 0;j < n-1; j++){
                int a = state_split.get(i+j);
                int b = state_split.get(i+j+1);
                temp = (a>b) ? b*2 : a*2;
                area -= temp;
            }
        }
        //4
        for(int i = 0;i < n*(n-1);i++){
            int a = state_split.get(i);
            int b = state_split.get(i+n);
            temp = (a>b) ? b*2 : a*2;
            area -= temp;
        }
        return area;
    }

}

2017/02/21 23:11

KimSeonbin

MATLAB 코드입니다.
단순하게 위,아래,좌,우 비교하면서 더했습니다.


% a=[1,4,3,4;
%     2,3,4,1;
%     3,4,2,1;
%     9,3,2,1]

% input the first row
input_first=input('row 1 : ','s');
row_first=str2num(input_first);
N=length(row_first);
a=zeros(N,N);
a(1,:)=row_first;
for p=2:N
    tmp_txt=input(sprintf('row %d :',p),'s');
    a(p,:)=str2num(tmp_txt);
end

area_sum=0;
for p=1:N
    for q=1:N
        % north
        if p==1
            area_sum=area_sum+a(p,q);
        else
            if a(p,q)>a(p-1,q)
                area_sum=area_sum+a(p,q)-a(p-1,q);
            end
        end
        % south
        if p==N
            area_sum=area_sum+a(p,q);
        else
            if a(p,q)>a(p+1,q)
                area_sum=area_sum+a(p,q)-a(p+1,q);
            end
        end
        % west
        if q==1
            area_sum=area_sum+a(p,q);
        else
            if a(p,q)>a(p,q-1)
                area_sum=area_sum+a(p,q)-a(p,q-1);
            end
        end
        % east
        if q==N
            area_sum=area_sum+a(p,q);
        else
            if a(p,q)>a(p,q+1)
                area_sum=area_sum+a(p,q)-a(p,q+1);
            end
        end
        % top
        area_sum=area_sum+1;
        % bottom
        area_sum=area_sum+1;
    end
end

disp(['겉넓이 : ' num2str(area_sum)]);

2017/03/02 10:21

c0din9

MATLAB의 sum, diff, abs 등의 함수를 이용해서 한 줄로 구해봤습니다.

% input the first row
input_first=input('row 1 : ','s');
row_first=str2num(input_first);
N=length(row_first);
a=zeros(N,N);
a(1,:)=row_first;
for p=2:N
    tmp_txt=input(sprintf('row %d :',p),'s');
    a(p,:)=str2num(tmp_txt);
end

% 면적 구하는 부분
area_sum2=
    sum(sum(abs(diff(a,1,1))))+...
    sum(sum(abs(diff(a,1,2))))+...
    sum(a(:,1))+sum(a(:,end))+sum(a(1,:))+sum(a(end,:))+...
    2*size(a,1)*size(a,2);

disp(['겉넓이 : ' num2str(area_sum2)]);  

2017/03/02 12:40

c0din9

import java.util.ArrayList;
import java.util.List;

public class OutsideArea {
    public static void main(String[] args) {
        Integer n = 4;
        Integer[][] m = {{1, 4, 3, 4}, {2, 3, 4, 1}, {3, 4, 2, 1}, {9, 3, 2, 1}};
        List<List<Integer>> l = new ArrayList<>();
        List<Integer> s = new ArrayList<>();
        Integer d = n * n * 2;

        for (int i = 0; i < n; i++) {
            List h = new ArrayList(n);
            List v = new ArrayList(n);
            for (int j = 0; j < n; j++) {
                h.add(m[i][j]);
                v.add(m[j][i]);
            }
            l.add(h);
            l.add(v);
        }

        l.stream().filter(i -> i.add(0)).forEach(j -> j.stream().reduce(0, (a, b) -> {
            s.add(Math.abs(a - b));
            return b;
        }));

        System.out.println(s.stream().mapToInt(Integer::intValue).sum() + d);
    }
}

2017/03/19 19:15

genius.choi

object Boxes
{
  private val A = List[List[Int]](List(1,4,3,4),List(2,3,4,1),List(3,4,2,1),List(9,3,2,1))
  def ToUns(Num : Int) : Int = if(Num > 0) Num else 0
  def up(BOXES : List[List[Int]], IND1 : Int, IND2 : Int): Int = if(IND1 == 0) 0 else BOXES(IND1 - 1)(IND2)
  def down(BOXES : List[List[Int]], IND1 : Int, IND2 : Int): Int = if(IND1 == BOXES.length - 1) 0 else BOXES(IND1 + 1)(IND2)
  def left(BOXES : List[List[Int]], IND1 : Int, IND2 : Int): Int = if(IND2 == 0) 0 else BOXES(IND1)(IND2 - 1)
  def right(BOXES : List[List[Int]], IND1 : Int, IND2 : Int): Int = if(IND2 == BOXES.length - 1) 0 else BOXES(IND1)(IND2 + 1)
  def CountBox(BOX : Int,B1 : Int,B2 : Int,B3 : Int,B4 : Int): Int = ToUns(BOX - B1) + ToUns(BOX - B2) + ToUns(BOX - B3) + ToUns(BOX - B4)
  def IntegralCB(BOXES : List[List[Int]], IND1 : Int, IND2 : Int): Int =
    CountBox(BOXES(IND1)(IND2), up(BOXES, IND1, IND2), down(BOXES, IND1, IND2), left(BOXES, IND1, IND2), right(BOXES, IND1, IND2))
  def CBREC(BOXES : List[List[Int]], IND1 : Int, IND2 : Int, Result : Int): Int =
    {
      if(IND2 < BOXES.length - 1) CBREC(BOXES, IND1, IND2 + 1, Result + IntegralCB(BOXES, IND1, IND2))
      else if(IND1 < BOXES.length -1) CBREC(BOXES, IND1 +1, 0, Result + IntegralCB(BOXES, IND1, IND2))
      else Result + IntegralCB(BOXES,IND1,IND2)
    }
  def main(args: Array[String]): Unit = print(CBREC(A, 0, 0, A.length * A.length * 2))
}
//Scala

굉장히 재밌는 문제였습니다. 아직 난잡하니 더 정리해서 다시 올리겠습니다.

2017/07/18 15:57

S ReolSt

box, N, area = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]], 4, 0

for i in range(N):
    for j in range(N):
        area += 2
        for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
            if 0 <= i+dx < N and 0 <= j+dy < N:
                area += max(0, box[i][j] - box[i+dx][j+dy])
            else:
                area += box[i][j]

print(area)

2017/08/20 23:32

Noname

import numpy as np

def count(t, nb):
    high=np.max(t)
    boo={}
    for i in range(1, high+1):
        boo[i]=(t>=i)
    result=0
    def inner(b, h, nbp, r, where=1):
        for i in range(nbp):
            for j in range(nbp):
                if b[where][i][j]:
                    if i+1==nbp or not b[where][i+1][j]: r+=1
                    if not i or not b[where][i-1][j]: r+=1
                    if j+1==nbp or not b[where][i][j+1]: r+=1
                    if not j or not b[where][i][j-1]: r+=1
        where+=1
        if where>h: return(r+np.count_nonzero(b[1])*2)
        else: return(inner(b, h, nbp, r, where))
    return(inner(boo, high, nb, result))

n=int(input())
tile=np.random.randint(0, 10, (n,n))

print(tile)
print(count(tile, n))

2017/12/20 23:29

빗나감

파이썬 3.6

def area(data):
    S,s_under_roof,side_south,side_east,side_west,inner_row,inner_column=0,0,0,0,0,0,0
    inner_list = []
    n = len(data)
# 윗면 아랫면 넓이 : 총 칸의 수 * 2 (바닥이 안보이도록 쌓으므로)
    s_under_roof = n * n * 2
# 옆면 넓이 (남,동,서,북 방향) : 각 방향별로 상자들이 쌓인수
    side_south = sum(data[0])
    for i in range(n):
        side_east += data[i][n-1]
        side_west += data[i][0]
    side_north = sum(data[n-1])
# 안쪽면 넓이(가로,세로 방향) : 각 행,열별로 인접 위치끼리 상자를 쌓은 수의 차의 절대값
    for i in data:
        inner_row = abs(i[0]-i[1])+abs(i[1]-i[2])+abs(i[2]-i[3])
        inner_list.append(inner_row)
    for i in zip(data[0],data[1],data[2],data[3]):
        inner_column = abs(i[0]-i[1])+abs(i[1]-i[2])+abs(i[2]-i[3])
        inner_list.append(inner_column)
    S = s_under_roof + side_south + side_east + side_west + side_north + sum(inner_list)
    print(S)

if __name__ == "__main__":
    data = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
    area(data)
  • 결과값
120

2018/01/17 15:18

justbegin

직사각형 가정으로 풀이합니다.

side_area: 좌우 옆 2면을 구한다

transpose: 행렬을 전치한다.

outside_area: 좌우 옆면을 더하고, 전치한 후 다시 옆면을 더하고, 행과 열을 곱한 수의 두배를 더한다.

# 파이썬

input_sample = [[1, 4, 3, 4], [2, 3, 4, 1], [3, 4, 2, 1], [9, 3, 2, 1]]


def transpose(l1):
    row = len(l1)
    column = len(l1[0])
    transposed = [[0 for _ in range(row)] for _ in range(column)]
    for m in range(column):
        for n in range(row):
            transposed[m][n] = l1[n][m]
    return transposed


def side_area(l1):
    area = 0
    for m in l1:
        area += m[0] + m[-1]
        for n in range(len(m)-1):
            area += abs(m[n] - m[n+1])
    return area


def outside_area(l1):
    return side_area(l1) + side_area(transpose(l1)) + (len(l1)*len(l1[0]))*2


print(outside_area(input_sample))

2018/01/31 17:23

olclocr

def surface(a):
    surface = 2*len(a)*len(a)
    for i in range(len(a)):
        for j in range(len(a)):
            surface += a[i][j]*4
    for i in range(len(a)):
        for j in range(len(a)-1):
            surface -= 2*(min(a[i][j], a[i][j+1])+min(a[j][i], a[j+1][i]))
    return surface


print(surface([[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]))

2018/02/14 10:24

김동하

Python

box = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
n = 4
ans = 0
for i in range(n):
    for j in range(n):
        for k in range(4):
            nx = i + dx[k]
            ny = j + dy[k]
            if 0 <= nx < n and 0 <= ny < n:
                if box[nx][ny] < box[i][j]:
                    ans += box[i][j] - box[nx][ny]
            else:
                ans += box[i][j]
ans += 2 * n * n
print(ans)

2018/06/12 14:46

Taesoo Kim


public class Main {
    public static void main(String[] args) {
        Integer[][] sqr = { { 1, 4, 3, 4 }, { 2, 3, 4, 1 }, { 3, 4, 2, 1 }, { 9, 3, 2, 1 } };
        int sum = 0;
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++) {
                int temp = sqr[i][j] * 4 + 2;
                temp -= i - 1 > -1 ? sqr[i - 1][j] > sqr[i][j] ? sqr[i][j] : sqr[i - 1][j] : 0;
                temp -= j - 1 > -1 ? sqr[i][j - 1] > sqr[i][j] ? sqr[i][j] : sqr[i][j - 1] : 0;
                temp -= i + 1 < 4 ? sqr[i + 1][j] > sqr[i][j] ? sqr[i][j] : sqr[i + 1][j] : 0;
                temp -= j + 1 < 4 ? sqr[i][j + 1] > sqr[i][j] ? sqr[i][j] : sqr[i][j + 1] : 0;
                sum += temp;
            }
        System.out.println(sum);
    }
}

2018/06/27 20:22

김지훈

#쌓여있는 정육면체상자들의 겉넓이
#단, 각 정육면체상자의 변의 길이는 모두 1이다.
n=int(input('바닥크기 입력: '))
ls=[]
for i in range(0,n):#행부터 입력
    mm=[]
    for j in range(0,n):
        m=int(input('상자 수 입력: '))
        mm.append(m)
    ls.append(mm)
print(ls)

#겹쳐지는 넓이
def doub(x):
    s=[0]
    co=0
    for r in range(0,len(x)-1):
        if x[r]>=x[r+1] and s[r]==0 and r!=len(x)-2 and co==0:
            s1=(x[r]-x[r+1])
            s.append(s1)
            co=1
        elif co==1 and x[r]>=x[r+1]:
            co=0
            s.append(0)
            s[r]=0
        else:
            s.append(0)
    return sum(s)

#윗/밑면
s1=2*(n**2-ls.count(0))#(전체 칸 수-상자의 개수가 0인 칸 수)*2
#앞/뒤
side1=0
for i in range(0,n):
    row=[]
    for j in range(0,n):
        row.append(ls[i][j])
    s3=doub(row)
    side1+=(max(row)+s3)
#좌/우    
side2=0
for j in range(0,n):
    col=[]
    for i in range(0,n):
        col.append(ls[i][j])
    s4=doub(col)
    side2+=(max(col)+s4)
s2=2*(side1+side2)
#총 겉넓이
s=s1+s2
print('구하는 겉넓이: ',s)

2019/01/24 17:17

GammaKnight

음영지역 부분에서 좀 고민했네요.

def boxes(n):

    bs = []

    for x in range(n):
        bs.append(list(map(int,input().split())))

    ans = n*n*2

    for y in range(n):

        v,h = bs[y],list(bs[x][y] for x in range(n))
        ans += (max(h)+max(v))*2

        for i in range(1,n-1):
            for t in [v,h]:
                    if max(x-t[i] for x in t[i+1:]) > 0 and max(x-t[i] for x in t[:i]) > 0:
                        ans += 2

    return ans

2019/01/28 16:57

김영성

def sol(mat) :
    result, vec = 0, [[1, 0], [0, 1], [-1, 0], [0, -1]]
    for s in mat :
        result += (2*len(s))+(4*sum(s))

    for m in range(0, len(mat)) :
        for n in range(0, len(mat)) :
            for v in vec :
                try :
                    if mat[m+v[0]][n+v[1]] <= mat[m][n] and m+v[0] >= 0 and n+v[1] >= 0 :
                        result -= mat[m+v[0]][n+v[1]]
                    elif mat[m+v[0]][n+v[1]] > mat[m][n] and m+v[0] >= 0 and n+v[1] >= 0 :
                        result -= mat[m][n]
                except :
                    continue

    return result

if __name__ == "__main__" :
    print(sol([[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]))

인접해있는 상자로 인해 겉넓이에서 제외되는 경우를 빼는 식으로 계산했습니다.

결과

120

2020/08/27 17:43

GG

// Rust

// 0개가 쌓여있지 않으면, 기본적으로 위에서볼때 아래에서볼때 2*n^2의 면적이 더해집니다.

// 각 위치(i,j)별로, 주변 4개의 숫자와 비교해서 큰만큼 면적이 더해집니다.

// Rust는 인덱스 접근이 조심스러워 가장자리를 포함해서 각 (i,j)에서 비교할 수 있는 위치들을 벡터에 넣어 더해갔습니다.

fn stacked_box() {

let input = [[1,4,3,4],[2,3,4,1],[3,4,2,1],[9,3,2,1]];

let n = input.len();
let mut tot = 2 * n * n;
for i in 0..n {
    for j in 0..n {
        let mut envi = vec![];
        let mut envj = vec![];
        let d = input[i][j];
        if i==0 { envi.push(i+1); tot += d;}
        else if i==n-1 { envi.push(i-1); tot += d;}
        else {envi.push(i+1); envi.push(i-1);}
        if j==0 { envj.push(j+1); tot += d;}
        else if j==n-1 { envj.push(j-1); tot += d;}
        else {envj.push(j+1); envj.push(j-1);}

        for k in envi { if d > input[k][j] { tot += d - input[k][j];}}
        for l in envj { if d > input[i][l] { tot += d - input[i][l];}}
    }
}
println!("{}", tot);

}

2022/02/01 13:38

JW KIM

numBoxes = [[1,4,3,4], [2,3,4,1], [3,4,2,1], [9,3,2,1]]
n = len(numBoxes)
sumSurface = 0
for i in range(n):
    sumSurface += numBoxes[i][0] + numBoxes[0][i]
    for j in range(n-1):
        if numBoxes[i][j] >0:
            sumSurface += 2
        sumSurface += abs(numBoxes[i][j]-numBoxes[i][j+1])
        sumSurface += abs(numBoxes[j][i] - numBoxes[j+1][i])
    if numBoxes[i][n-1] > 0:
        sumSurface += 2 + numBoxes[i][n-1] + numBoxes[n-1][i]
print(sumSurface)

2023/11/05 19:58

insperChoi

목록으로