Spiral Array

문제는 다음과 같다:

6 6

  0   1   2   3   4   5
 19  20  21  22  23   6
 18  31  32  33  24   7
 17  30  35  34  25   8
 16  29  28  27  26   9
 15  14  13  12  11  10

위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

132개의 풀이가 있습니다. 1 / 14 Page

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[] ) {

        int row, column;    // 행, 열
        int inc=0;              // 2차원 배열에 입력 방향에 따른 입력 시작/종료 위치 보정을 위한 값
        int num=0;              // 0~(row*colunm-1), ex) 3x4 → 0~11

        row=atoi(argv[1]);
        column=atoi(argv[2]);

        // 2차원 배열을 동적으로 생성
        int **matrix = (int **)malloc(sizeof(int *)*row);
        for(int i=0; i<row; i++) matrix[i] = (int *)malloc(sizeof(int)*column);


        // 각 방향(→, ↓, ←, ↑)에서 조건에 맞는 범위내에서 num을 증가시켜면서 2차원 배열에 값을 저장
        // num 값이 row * column 과 같으면 반복문을 빠져나옴
        // 한바퀴 돌때마다 inc 값을 증가시켜 각 for 문에서 입력의 시작/종료 시점을 보정
        while(1) {

            for(int i=inc; i<column-inc; i++) matrix[inc][i] = num++;
            if(num==row*column) break;

            for(int i=inc+1; i<row-inc; i++) matrix[i][column-inc-1] = num++;
            if(num==row*column) break;

            for(int i=column-1-1-inc; i>inc-1; i--) matrix[row-1-inc][i] = num++;
            if(num==row*column) break;

            for(int i=row-1-1-inc; i>inc-1+1; i--) matrix[i][inc] = num++;
            if(num==row*column) break;

            inc++;              
        }

        // 전체 배열 출력
        for(int i=0; i<row; i++) {
            for(int j=0; j<column; j++) printf("%3d", matrix[i][j]);    
            printf("\n");
        }

        // 동적 할당 해제
        for(int i=0; i<row; i++) free(matrix[i]);   
        free(matrix);

    return 0;
}

2017/03/23 17:43

jyc

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include <iostream>
using namespace std;

#define M   4
#define N   4

// matrix를 미리 정함
// 1  2  3  4
// 12 13 14 5
// 11 16 15 6
// 10 9  8  7

int main()
{
    int A[M][N] = { {1, 2, 3, 4}, {12, 13, 14, 5}, {11, 16, 15, 6}, {10, 9, 8, 7} };

    int x = 0;
    int y = 0;
    int dx = 0;
    int dy = 1;
    int min_x = 0;
    int max_x = M - 1;
    int min_y = 0;
    int max_y = N - 1;
    int i = 0;

    while (i < M * N)
    {
        cout << A[x][y] << endl;

        x += dx;
        y += dy;
        i++;

        if (y > max_y)
        {
            x++;
            y = max_y;
            dy = 0;
            dx = 1;
            min_x++;
        }
        else if (y < min_y)
        {
            x--;
            y = min_y;
            dy = 0;
            dx = -1;
            max_x--;
        }
        else if (x > max_x)
        {
            y--;
            x = max_x;
            dx = 0;
            dy = -1;
            max_y--;
        }
        else if (x < min_x)
        {
            y++;
            x = min_x;
            dx = 0;
            dy = 1;
            min_y++;
        }
    }

    return 0;
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include <iostream>
#include <iomanip>

using namespace std;

void getResult(int ** arr, int row, int col);

void main()
{
    int row = 0;        //행
    int col = 0;        //열
    int i = 0, j = 0;   //for문을 위한 카운터

    cin >> row >> col;

    int **arr = new int *[row];
    for (i = 0; i < row; i++)
    {
        arr[i] = new int[col];
    }

    getResult(arr, row, col);

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            cout << setfill(' ') << setw(2) << arr[i][j] << " ";
        }
        cout << endl;
    }

    return;
}

void getResult(int ** arr, int row, int col)
{
    int row_min = 0, row_max = row - 1;
    int col_min = 0, col_max = col - 1;
    int max_num = row * col - 1;
    int input_num = 0;
    int i = 0;

    while (1)
    {
        for (i = col_min; i <= col_max; i++)
        {
            arr[row_min][i] = input_num;
            input_num++;
        }
        row_min++;
        if (input_num > max_num) break;

        for (i = row_min; i <= row_max; i++)
        {
            arr[i][col_max] = input_num;
            input_num++;
        }
        col_max--;
        if (input_num > max_num) break;

        for (i = col_max; i >= col_min; i--)
        {
            arr[row_max][i] = input_num;
            input_num++;
        }
        row_max--;
        if (input_num > max_num) break;

        for (i = row_max; i >= row_min; i--)
        {
            arr[i][col_min] = input_num;
            input_num++;
        }
        col_min++;
        if (input_num > max_num) break;
        if (col_max < 0) break;
    }

    return;
}

행렬할 때마다 느끼는건데, row 랑 column 너무 햇갈려ㅠㅜ

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
 class Program
    {
        static void Main(string[] args)
        {
            int printNum = 0;
            string result = Console.ReadLine();
            List<int> inputNum = result.Split(' ').Select(x => Convert.ToInt32(x)).ToList();
            int input1 = inputNum[0];
            int input2 = inputNum[1];
            int[,] arrResult = new int[input1,input2];

            for(int  i= 0; i<input1/2; i++)
            {
                int num = (input2 - 1) - (i * 2);

                for (int a = 0; a < num; a++)
                {
                    arrResult[i, a+i] = printNum;
                    printNum++;
                }

                for (int b = 0; b < num; b++)
                {
                    arrResult[i+b, input2-i-1] = printNum;
                    printNum++;
                }

                for (int c = 0; c < num; c++)
                {
                    arrResult[input1-i-1, input2-c-i-1] = printNum;
                    printNum++;
                }

                for (int d = 0; d < num; d++)
                {
                    arrResult[input1-d-i-1, i] = printNum;
                    printNum++;
                }
            }

            if (input1 % 2 != 0)
            {
                arrResult[input1 / 2, input2 / 2] = printNum;
            }

            for (int i = 0; i < input1; i++)
            {
                for (int j = 0; j < input2; j++)
                {
                    Console.Write(arrResult[i, j] + " ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();

        }
    }
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
public class SpiralArray {
    public static void main(String[] args){
        int num1 = 8;
        int num2 = 9;
        int[][] arr = new int[num1][num2];
        int directionWidth =1;
        int directionHeight = 0;
        int move = 0;
        int width =0;
        int height =0;
        int direction =0;
        int directionNum =0;
        int directionNumTemp = -1;
        System.out.print(num1+" ");
        System.out.println(num2);
        for( int i = 0; i < num1*num2; i++){
            arr[height][width] = move;
            width += directionWidth;
            height += directionHeight;
            move++;

            if( (width == num2 - 1 - direction)&& (directionHeight == 0)&&(directionWidth ==1)){
                directionWidth = 0;
                directionHeight = 1;
                directionNum++;
            }

            else if( (height == num1-1 - direction)&&(directionWidth == 0)&&(directionHeight == 1)  ){
                directionHeight = 0;
                directionWidth = -1;
                directionNum++;
            }
            else if( (width == 0 +direction) && (directionHeight==0)&&(directionWidth == -1) ){
                directionWidth = 0;
                directionHeight = -1;
                directionNum++;
            }
            else if( (height ==  direction) && (directionWidth== 0)&&(directionHeight == -1)){
                directionHeight = 0;
                directionWidth = 1;
                directionNum++;
            }

            if (directionNum == 3){
                direction = 1;
            }else if( directionNum > 3 ){
                if( directionNumTemp != directionNum){
                    if( directionNum%4 ==3){
                        directionNumTemp = directionNum;
                        direction++;
                    }
                }
            }

        }
        for(int k =0; k<num1; k++){
            for(int l = 0; l<num2; l++){
                System.out.print(arr[k][l]);
            }
            System.out.println("");
        }
    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
/*************************************************************
6 6

  0   1   2   3   4   5
 19  20  21  22  23   6
 18  31  32  33  24   7
 17  30  35  34  25   8
 16  29  28  27  26   9
 15  14  13  12  11  10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*************************************************************/

#include<stdio.h>
#include<stdlib.h>

int** Make_2D_Arr(int column, int row);

int main(void)
{
    int** arr;
    int column, row, max_column, max_row,flag=0,min_column=0, min_row=1;
    int i,j=0,k=0;
    scanf("%d %d",&column,&row);

    arr = Make_2D_Arr(column, row);

    max_column  = column-1;
    max_row     = row-1;

    for(i=0;i<column*row;i++)
    {
        if(flag == 0)
        {
            arr[j][k]=i+1;
            if(k==max_column)
            {
                max_column--;
                flag++;
                j++;
            }
            else
            {
                k++;
            }
        }
        else if(flag == 1)
        {
            arr[j][k]=i+1;
            if(j==max_row)
            {
                max_row--;
                flag++;
                k--;
            }
            else
            {
                j++;
            }

        }
        else if(flag == 2)
        {
            arr[j][k]=i+1;
            if(k==min_column)
            {
                min_column++;
                flag++;
                j--;
            }
            else
            {
                k--;
            }
        }
        else if(flag == 3)
        {
            arr[j][k]=i+1;
            if(j==min_row)
            {
                min_row++;
                flag=0;
                k++;
            }
            else
            {
                j--;
            }
        }
    }

    for(i=0;i<row;i++)
    {
        for(j=0;j<column;j++)
        {
            printf("%2d ",arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

int** Make_2D_Arr(int column, int row)
{
    int     i;
    int**   p_arr;

    p_arr = (int**)malloc(row*sizeof(int*));

    for(i=0;i<row;i++)
    {
        p_arr[i] = (int *)malloc(column*sizeof(int));
    }

    return p_arr;
}

뭔가 어렵게 푼거같네요...

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
public class Spiral {
    static int insertX=0;
    static int insertY=0;
    static int x = 0;
    static int y = 0;
    static int xConvert = 0;
    static int yConvert = 0;
    static int[][] array;

    public static void main(String[] args) {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            System.out.print("x를 입력 : ");
            insertX = Integer.parseInt(br.readLine());
            System.out.print("y를 입력 : ");
            insertY = Integer.parseInt(br.readLine());
            array = new int[insertX][insertY];
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }

        for(int i=0; i<insertX; i++){
            for(int j=0; j<insertY; j++){
                array[i][j] = -1;
            }
        }
        for(int i=0; i<insertX*insertY; i++){

            if(xConvert == 0 && yConvert == 0){//가로가 오른쪽으로  
                array[x][y++] = i;
                if(insertY == y || array[x][y] != -1){//가로 증가 세로 고정
                    x++;
                    y--;
                    yConvert = -1;
                    continue;
                }
            }else if(xConvert == 0 && yConvert == -1){//세로가 밑으로
                array[x++][y] = i;
                if(insertX == x || array[x][y] != -1){//가로 고정 세로로 증가
                    x--;
                    y--;
                    xConvert = -1;
                    yConvert = 0;
                    continue;
                }
            }else if(xConvert == -1 && yConvert == 0){//가로가 왼쪽으로
                array[x][y--] = i;
                if(y < 0 || array[x][y] != -1){//가로 감소 세로 고정
                    x--;
                    y++;
                    xConvert = -1;
                    yConvert = -1;
                    continue;
                }   
            }else if(xConvert == -1 && yConvert == -1){//세로가 위쪽으로
                array[x--][y] = i;
                if(x < 0 || array[x][y] != -1){//가로 고정 세로 감소
                    x++;
                    y++;
                    xConvert = 0;
                    yConvert = 0;
                    continue;
                }

            }
        }
        for(int i=0; i<3; i++){
            for(int j=0; j<3; j++){
                System.out.print(array[i][j]+"  ");
            }
            System.out.println("");
        }
    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

변수 선언이 많은 편인가요? 저한텐 이렇게 하는 게 가장 이해하기 쉽네요..

#include <iostream>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
using namespace std;

/* http://codingdojang.com/scode/266
문제는 다음과 같다:

6 6

0   1   2   3   4   5
19  20  21  22  23   6
18  31  32  33  24   7
17  30  35  34  25   8
16  29  28  27  26   9
15  14  13  12  11  10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/

int main() {
    int **matrix;
    int rowCount, colCount;
    int rowIndex = 0, colIndex = 0;
    int rowTopLimit = 1, rowBottomLimit;
    int colLeftLimit = 0, colRightLimit;
    int direction;
    int element = 0;

    cin >> colCount >> rowCount;
    rowBottomLimit = colCount - 1;
    colRightLimit = rowCount - 1;

    matrix = new int *[rowCount];
    for (int i = 0; i < rowCount; i++) {
        matrix[i] = new int[colCount];
    }

    direction = RIGHT;
    while (element < rowCount * colCount) {
        matrix[rowIndex][colIndex] = element;
        element++;

        switch (direction) {
        case UP:
            rowIndex--;

            if (rowIndex == rowTopLimit) {
                direction = RIGHT;

                rowTopLimit++;
            }
            break;
        case DOWN:
            rowIndex++;

            if (rowIndex == rowBottomLimit) {
                direction = LEFT;

                rowBottomLimit--;
            }
            break;
        case LEFT:
            colIndex--;

            if (colIndex == colLeftLimit) {
                direction = UP;

                colLeftLimit++;
            }
            break;
        case RIGHT:
            colIndex++;

            if (colIndex == colRightLimit) {
                direction = DOWN;

                colRightLimit--;
            }
            break;

        default:
            break;
        }
    }

    for (int i = 0; i < colCount; i++) {
        for (int j = 0; j < rowCount; j++) {
            cout << matrix[i][j] << " ";
        }

        cout << endl;
    }

    return 0;
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

python 3.5.2

answer is

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 11], [32, 59, 60, 61, 62, 63, 64, 65, 66, 43, 12], [31, 58, 77, 78, 79, 80, 81, 82, 67, 44, 13], [30, 57, 76, 87, 86, 85, 84, 83, 68, 45, 14], [29, 56, 75, 74, 73, 72, 71, 70, 69, 46, 15], [28, 55, 54, 53, 52, 51, 50, 49, 48, 47, 16], [27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17]]

  • 11*8 인 경우 이동거리 lst 가 0 또는 0보다 작은 값을 갖으며 오류를 만들 가능성이 있어 for문에 break 추가하였음.
# r,c = map(int,input().split(' '))

r=8
c=11

lst = list()
array=[[0 for x in range(c)] for x in range(r)]

row,col = r,c

cnt=0
curr_point=(0,0)
curr_direct='right'

move = {
    'up':(-1,0),
    'down':(1,0),
    'right':(0,1),
    'left':(0,-1)
}

next_direct={
    'up':'right',
    'right':'down',
    'down':'left',
    'left':'up'
}
# 움직일 거리를 list 에 담는다.
for i in range(r+c-1):
    if i%2 == 0 :
        if i==0 :
            pass
        else :
            c -= 1
        if c == 0 :
            break
        else :
            lst.append(c)
    else :
        r -= 1
        if r == 0 :
            break
        else :
            lst.append(r)


# 숫자 기입
for i in lst :
    for j in range(i):
        array[curr_point[0]][curr_point[1]] = cnt
        cnt += 1
        if (j == (i-1)) :
            curr_direct = next_direct[curr_direct]
        curr_point = tuple(map(sum,zip(curr_point, move[curr_direct])))


array

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
# Get & validate input values
while True:
    inp = input()
    if len(inp) < 3:
        print('Invalid input.')
        continue

    inps = inp.split(' ')
    rows = int(inps[0])
    cols = int(inps[1])

    if rows <= 0 or cols <= 0:
        print('Invalid input.')
        continue

    break

# Prepare numbers to fill
nums = list(range(rows*cols))
# filling direction
dirc = [[0, 1], [1, 0], [0, -1], [-1, 0]]
# Prepare empty spiral matrix
spmatrix = [[-1 for col in range(cols)] for row in range(rows)]

# Fill spiral matrix
i = 0
r = 0
c = 0
dmode = 0
while i < rows*cols:
    spmatrix[r][c] = nums[i]

    tmp_r = r + dirc[dmode][0]
    tmp_c = c + dirc[dmode][1]

    # Inspect conditions to change direction
    if  tmp_r < 0 or tmp_r  >= rows or tmp_c < 0 or tmp_c >= cols  or spmatrix[tmp_r][tmp_c] !=-1:
        dmode +=1
        dmode %= 4

    r += dirc[dmode][0]
    c += dirc[dmode][1]

    i += 1

# Print the result
for i in range(rows):
    for j in range(cols):
        print("{0:>2}".format(spmatrix[i][j]), end=' ')
    print();

매 루프마다 채우는 방향을 바꿔야 하는 조건을 테스트하는 방식으로 풀었습니다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 132
기 타 x 12
cpp x 34
cs x 6
java x 27
python x 41
javascript x 1
delphi x 1
go x 1
ruby x 2
lisp x 2
objectivec x 1
clojure x 1
scala x 3