2011년6월15일_달팽이 배열
[달팽이 배열]
N*N 정방행렬에 달팽이 집과 같은 순서로 데이터를 저장한다.
달팽이 배열은 배열의 크기나 시계 방향 또는 반시계 방향 어디든지 상관 없으나, 이 문제에서는 외부에서 중심까지 시계 방향으로 회전시키는 경우를 다룬다.
<해법>
열의 최대값을 담을 변수
열의 최소값을 담을 변수
행의 최대값을 담을 변수
행의 최소값을 담을 변수와 행, 열을 비교하여,
최초 열을 증가시켜,
①열의 최대값과 같거나 크면 행의 최대값을 -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 /*열의 크기 (여기만 수정하면 배열의 크기가 바뀜)*/
1: #define ROW 5 //행의 크기
2: #define COL 5 /*열의 크기 (여기만 수정하면 배열의 크기가 바뀜)*/