2011년6월15일_달팽이 배열

 

 

 

[달팽이 배열]

N*N 정방행렬에 달팽이 집과 같은 순서로 데이터를 저장한다.

달팽이 배열은 배열의 크기나 시계 방향 또는 반시계 방향 어디든지 상관 없으나, 이 문제에서는 외부에서 중심까지 시계 방향으로 회전시키는 경우를 다룬다.

image

 

 

DSCN3373

 

<해법>

열의 최대값을 담을 변수
열의 최소값을 담을 변수
행의 최대값을 담을 변수
행의 최소값을 담을 변수와 행, 열을 비교하여,

최초 열을 증가시켜,
①열의 최대값과 같거나 크면 행의 최대값을 -1하고 행을 증가시키는 쪽으로 방향전환,
②행의 최대값과 같거나 크면 열의 최소값을 +1하고 열을 감소시키는 쪽으로 방향전환,
③열의 최소값과 같거나 작으면 행의 최소값을 +1하고 행을 감소키는 쪽으로 방향전환,
④행의 최소값과 같거나 작으면 열의 최대값을 -1하고 열을 증가시키는 쪽으로 방향전환하고 ①부터 반복

 

<소스코드>

   1:  /********************************************************************
   2:  
   3:      1.  4X4 정방행렬에 달팽이 집과 같은 순서로 숫자 1부터 차례대로
   4:          기억시킨 후, 그 값을 출력하시오.
   5:          
   6:      작성자: 김수만
   7:      작성일자: 2011년 6월 15일
   8:      
   9:  ********************************************************************/
  10:  #include <stdio.h>
  11:   
  12:  #define    ROW    4        //행의 크기 
  13:  #define    COL    4        //열의 크기 (여기만 수정하면 배열의 크기가 바뀜)
  14:   
  15:   
  16:  void Set_Snail_Array(int (*pArr)[COL]);
  17:  void View_2Div_Array(int (*pArr)[COL]);
  18:   
  19:   
  20:  int main()
  21:  {
  22:      int aArr[ROW][COL] = {0,};        //배열을 초기화, 꼭 할 필요는 없음.
  23:      
  24:      Set_Snail_Array(aArr);            //달팽이 배열 생성.
  25:      View_2Div_Array(aArr);            //2차원 배열에 들은 값을 보기 좋게 출력
  26:   
  27:      return 0;
  28:  }
  29:      
  30:  //2차원 배열에 달팽이 배열 모양으로 값을 입력
  31:  void Set_Snail_Array(int (*pArr)[COL])
  32:  {
  33:      int iRow = 0;                //제어변수
  34:      int iCol = 0;                //제어변수
  35:      int iSeq = 1;                //행과 열 증감제어
  36:      int iRow_Max = ROW + 1;        //행의 최대값
  37:      int iCol_Max = COL;            //열의 최대값
  38:      int iRow_Min = 0;            //행의 최소값
  39:      int iCol_Min = -1;            //열의 최소값
  40:      int iNum = 1;                //배열에 대입할 초기값
  41:   
  42:      //달팽이~
  43:      while((ROW * COL) >= iNum)        //배열의 크기만큼 반복
  44:      {
  45:          if(0 != iSeq)                //평상시
  46:          {
  47:              pArr[iRow][iCol] = iNum;
  48:              ++iNum;
  49:          }
  50:          else                        //방향을 3번 바꾼 뒤
  51:          {
  52:              ++iSeq;                    //iSeq = 0에서 1이 된다.
  53:          }
  54:   
  55:          //디버그용 코드
  56:          //printf("(%d,%d) = %3d,\t%d", iRow, iCol, *(*(pArr + iRow) + iCol), iSeq);
  57:          //getchar();
  58:   
  59:          
  60:          //방향제어
  61:          if(1 == iSeq)                //열++ 시퀀스
  62:          {
  63:              ++iCol;
  64:              
  65:              if(iCol_Max <= iCol)    //열의 상한
  66:              {
  67:                  ++iSeq;
  68:                  --iCol;
  69:                  --iRow_Max;            //행의 최대값을 줄임 (배열 안으로 향함)
  70:              }
  71:          }
  72:   
  73:          if(2 == iSeq)                //행++ 시퀀스
  74:          {
  75:              ++iRow;
  76:              
  77:              if(iRow_Max <= iRow)    //행의 상한
  78:              {
  79:                  ++iSeq;
  80:                  --iRow;
  81:                  ++iCol_Min;            //열의 최소값을 늘림 (배열 안으로 향함)
  82:              }
  83:          }
  84:   
  85:          if(3 == iSeq)                //열-- 시퀀스
  86:          {
  87:              --iCol;
  88:              
  89:              if(iCol_Min > iCol)        //열의 하한
  90:              {
  91:                  ++iSeq;
  92:                  ++iCol;
  93:                  ++iRow_Min;            //행의 최소값을 늘림 (배열 안으로 향함)
  94:              }
  95:          }
  96:          
  97:          if(4 == iSeq)                //행-- 시퀀스
  98:          {
  99:              --iRow;
 100:              
 101:              if(iRow_Min > iRow)        //행의 하한
 102:              {
 103:                  ++iSeq;
 104:                  ++iRow;
 105:                  --iCol_Max;            //열의 최대값을 줄임 (배열 안으로 향함)
 106:              }
 107:          }
 108:          
 109:          if(4 < iSeq)                //4번째 시퀀스가 끝이니 0으로 초기화해
 110:          {                            //다시 0부터 돌게 함.
 111:              iSeq = 0;
 112:          }
 113:          
 114:      }
 115:      
 116:      return ;
 117:  }
 118:   
 119:  //2차원 배열의 값을 출력.
 120:  void View_2Div_Array(int (*pArr)[COL])
 121:  {
 122:      int iRow;
 123:      int iCol;
 124:      
 125:      //배열에 있는 값을 순차적으로 출력
 126:      for(iRow = 0 ; ROW > iRow ; ++iRow)
 127:      {
 128:          for(iCol = 0 ; COL > iCol ; ++iCol)
 129:          {
 130:              printf("%3d", pArr[iRow][iCol]);
 131:          }
 132:          
 133:          putchar('\n');
 134:      }
 135:   
 136:      return ;
 137:  }

 

상기의 소스코드를 수정할 필요없이 아래와 같이 행과 열의 크기만 바꾸면 크기가 자동으로 가변됨.

   1:  #define    ROW    4        //행의 크기 
   2:  #define    COL    4        /*열의 크기 (여기만 수정하면 배열의 크기가 바뀜)*/

 

image

 

 

   1:  #define    ROW    5        //행의 크기 
   2:  #define    COL    5        /*열의 크기 (여기만 수정하면 배열의 크기가 바뀜)*/

image