DY N DY

실력키우기 문자마름모(JAVA) 본문

PARK/ALGORITHM

실력키우기 문자마름모(JAVA)

손세지 2016. 5. 12. 11:29

1331 : 문자마름모

제한시간: 1Sec    메모리제한: 64mb
해결횟수: 510회    시도횟수: 2094회   



마름모의 한 변의 길이 N을 입력받아 아래와 같이 문자마름모를 출력하는 프로그램을 작성하시오.


< 처리조건 > 
(1) 첫 번째 행의 중앙부터 출발하여 시계 반대방향으로 'A'부터 차례대로 채워나간다. ('Z'다음에는 다시 'A'가 된다.)
(2) 바깥 부분이 다 채워지면 두 번째 행 중앙부터 다시 같은 작업을 반복한다.
(3) 같은 방법으로 마름모를 다 채워지도록 하여 출력한다.


e3050b66a1b29a01767400d7560a4131_1449725
 




 

마름모의 한변의 길이 N(N의 범위는 100 이하의 양의 정수)을 입력받는다.



주어진 형태대로 한변의 길이가 N인 문자마름모를 출력한다. 문자 사이는 한 개의 공백으로 구분한다.


 [Copy]
4
 [Copy]
      A
    B M L
  C N U T K
D O V Y X S J
  E P W R I
    F Q H
      G



  1. /**************************************************************
  2.     Problem: 1331
  3.     User: a132034
  4.     Language: Java
  5.     Result: Success
  6.     Time:1139 ms
  7.     Memory:40548 kb
  8. ****************************************************************/
  9.  
  10.  
  11. import java.util.Scanner;
  12.  
  13. public class Main{
  14.     public static void main(String[] args) {
  15.         Scanner sc = new Scanner(System.in);
  16.         int N = sc.nextInt();
  17.          
  18.         int min = 0;
  19.         int max = 2*N-2;
  20.         int[][] dia = new int[2*N-1][2*N-1];
  21.          
  22.         for(int x = 0 ; x < 2*N-1; ++x)
  23.         {
  24.             for(int y = 0 ; y < 2*N-1; ++y)
  25.             {
  26.                 dia[x][y] = ' ';
  27.             }  
  28.         }
  29.         int i=0, j = N-1;
  30.         int plus = 0;
  31.         boolean xflg = true, yflg = false;
  32.         while(max != min)
  33.         {
  34.              
  35.             dia[i][j] = 'A'+((plus++)%('Z'-'A'+1));
  36.              
  37.             if(== min+1 && j == N)//한 바퀴의 마지막
  38.             {
  39.                 min++;
  40.                 max--;
  41.                 xflg = true;
  42.                 yflg = false;
  43.                 i = min;
  44.                 j = N-1;
  45.                 if(max == min){
  46.                     dia[max][min] = 'A'+((plus++)%('Z'-'A'+1));
  47.                     break;
  48.                 }
  49.  
  50.                 dia[i][j] = 'A'+((plus++)%('Z'-'A'+1));
  51.             }
  52.              
  53.             if(== min)
  54.                 xflg = true;
  55.             if(== max)
  56.                 xflg = false;
  57.              
  58.             if(== min)
  59.                 yflg = true;
  60.             if(== max)
  61.                 yflg = false;
  62.              
  63.             if(xflg)
  64.                 i++;
  65.             else
  66.                 i--;
  67.              
  68.             if(yflg)
  69.                 j++;
  70.             else
  71.                 j--;
  72.              
  73.              
  74.              
  75.         }
  76.          
  77.          
  78.         for(int x = 0 ; x < 2*N-1; ++x)
  79.         {
  80.             for(int y = 0 ; y < 2*N-1; ++y)
  81.             {
  82.                 System.out.printf("%c ", dia[x][y]);
  83.             }
  84.             System.out.println();
  85.         }
  86.     }
  87. }



처음에는 노트에 한글자씩 써가면서 보통의 for loop 순서대로 어떻게 하면 될까... 골똘히 고민을 해봤다. 

규칙이 없는 것 같지는 않은데 너무 난해해서 결국 마름모 1/4정도까지만 어떻게 만든 후에 이건 아니다 싶은 마음에 방법을 바꿔 보았다. 

알파벳 순서로 좌표의 흐름을 생각해보았다. 

의외로 간단!


4를 기준으로 했을 떄 예를 들어

가장 길 떄의 길이(중간)는 2*N-1개 (여기서는 7개)의 알파벳이 한 row 또는 column에 들어가기 때문에 그것을 기준으로 배열을 만들었다.


배열의 시작은 0이지만 여기서는 생각하지 않고 1부터 시작하는 것으로 가정한다면

순서는 다음과 같다.

1,4 -> 2,3 -> 3,2 -> 4,1 -> 5,2 -> 6,3 -> 7,4 -> 6,5 -> 5,6 -> 4,7 -> 3,6 -> 2,5 여기서 가장 큰 마름모가 전부 그려지게 된다. 

다음 마름모는 가로세로가 각각 2씩 줄어든 마름모 이므로 구현은 min, max를 각각 1씩 더하고 빼는 방법으로 하였다. 

다시 시작은 한칸 내려간 2번쨰 줄의 중간부터 시작 

2,4 -> 3,3 -> 4,2 -> 5,3 -> 6,4 -> 5,5 -> 4,6 -> 3,5 이것으로 두번쨰로 큰 마름모가 전부 그려지게 된다. 

이렇게 반복하면서 얻은 규칙은


1. x축과 y축이 모두 끝에 도달하면 방향이 반대로 바뀐다.

2. 마름모의 마지막에 도달했을 때 더 작은 마름모로 가기 위해 값을 초기화 해주고, 구현상의 min, max를 1씩 증가,감소 해준다. (총 2의 길이 감소)

3. N개 만큼의 마름모가 만들어 지거나, 구현상에서는 min = max가 되거나, 혹은 i, j가 중간값(N,N)이 되었을 경우... 등등 전부 동일한 경우이나 어쨋든 모든 루프가 종료된다. 



이걸 그대로 코드로 반영하기 위해 min, max값을 사용했다. 그외 특이사항은 없다.