C++ Rookiss Part1 C++ 프로그래밍 입문 : 연습문제(달팽이)
🙇♀️연습문제(달팽이)
숫자를 입력받으면 N*N 규칙이 있는 숫자판을 그린다.
ex) 4 입력
// 01 02 03 04
// 12 13 14 05
// 11 16 15 06
// 10 09 08 07
🪐연습문제(달팽이)
🪐내가 생각한 방법(실패)
void setboard()
{
for (int i = 0; i < n; i++) // 1 - 1
{
board[0][i] = i + 1;
}
for (int i = 0; i < n - 1; i++) // 2 - 1 // 2 - 2
{
board[i + 1][n - 1] = n + 1 + i;
board[n - 1][i] = 3 * n - 2 - i;
}
for (int i = 0; i < n - 2; i++) // 3 - 1 // 3 - 2
{
board[i + 1][0] = 4 * n - 4 - i;
board[1][i + 1] = 4 * n - 4 + i + 1;
}
for (int i = 0; i < n - 3; i++) // 4 - 1 // 4 - 2
{
board[i + 2][n - 2] = 5 * n - 5 + i;
board[n - 2][i + 1] = 7 * n - 12 - i;
}
for (int i = 0; i < n - 4; i++) // 5 - 1 // 5 - 2
{
board[i + 2][1] = 8 * n - 16 - i;
board[2][i + 2] = 8 * n - 16 + i + 1;
}
for (int i = 0; i < n - 5; i++) // 6 - 1 // 6 - 2
{
board[i + 3][n - 3] = 9 * n - 19 + i;
board[n - 3][i + 2] = 11 * n - 30 - i;
}
for (int i = 0; i < n - 4; i++) // 7 - 1 // 7 - 2
{
board[i + 3][2] = 12 * n - 36 - i;
board[3][i + 3] = 12 * n - 36 + i + 1;
}
}
난 이 문제를 풀 때 패턴을 찾고 그 규칙에 맞게 for문을 합치려 했는데 실패함. 빙글빙글 돌아가니까 각 줄마다의 규칙을 찾았는데 패턴식으로 풀려면 다른 방법을 찾아야 할 듯. 짝수번끼리 홀수번끼리 for문을 합치는 방법을 모르겠음.
🪐rookiss 방법
#include <iostream>
using namespace std;
#pragma warning(disable: 4996)
#include <iomanip>
// 오늘의 주제 : 연습문제 (달팽이)
const int Max = 100;
int board[Max][Max] = {};
int N;
void printboard()
{
for (int y = 0; y < N; y++)
{
for (int x = 0; x < N; x++)
{
cout << setfill('0') << setw(2) << board[y][x] << " ";
}
cout << endl;
}
}
enum DIR
{
RIGHT = 0,
DOWN = 1,
LEFT = 2,
UP = 3,
};
bool CanGo(int y, int x)
{
if (y < 0 || y >= N)
return false;
if (x < 0 || x >= N)
return false;
if (board[y][x] != 0)
return false;
return true;
}
void setboard()
{
int dir = RIGHT;
int num = 1;
int y = 0;
int x = 0;
while (true)
{
board[y][x] = num;
if (num == N * N)
break;
int nextY;
int nextX;
switch (dir)
{
case RIGHT:
nextY = y;
nextX = x + 1;
break;
case DOWN:
nextY = y + 1;
nextX = x ;
break;
case LEFT:
nextY = y;
nextX = x - 1;
break;
case UP:
nextY = y - 1;
nextX = x;
break;
}
if (CanGo(nextY, nextX))
{
y = nextY;
x = nextX;
num++;
}
else
{
switch (dir)
{
case RIGHT:
dir = DOWN;
break;
case DOWN:
dir = LEFT;
break;
case LEFT:
dir = UP;
break;
case UP:
dir = RIGHT;
break;
}
}
}
}
int main()
{
cin >> N;
setboard();
printboard();
return 0;
}
이 방법은 빙글빙글 돌아가는 숫자를 패턴이 아니라 하나하나 찍어가는 방식이다. 무슨 말이냐면 먼저 숫자를 찍으면 그 다음 방향으로 좌표를 넘어가서 숫자를 찍는 방법이다. 다음 방향으로 나아 갈 수 없다면 방향을 꺽어준다. N*N 번이 되면 반복을 멈춘다.
🪐rookiss 방법 보완
#include <iostream>
using namespace std;
#pragma warning(disable: 4996)
#include <iomanip>
// 오늘의 주제 : 연습문제 (달팽이)
const int Max = 100;
int board[Max][Max] = {};
int N;
void printboard()
{
for (int y = 0; y < N; y++)
{
for (int x = 0; x < N; x++)
{
cout << setfill('0') << setw(2) << board[y][x] << " ";
}
cout << endl;
}
}
bool CanGo(int y, int x)
{
if (y < 0 || y >= N)
return false;
if (x < 0 || x >= N)
return false;
if (board[y][x] != 0)
return false;
return true;
}
void setboard()
{
int dir = 0;
int num = 1;
int y = 0;
int x = 0;
int dy[] = { 0,1,0,-1 };
int dx[] = { 1,0,-1,0 };
while (true)
{
board[y][x] = num;
if (num == N * N)
break;
int nextY = y + dy[dir];
int nextX = x + dx[dir];
if (CanGo(nextY, nextX))
{
y = nextY;
x = nextX;
num++;
}
else
dir = (dir + 1) % 4;
}
}
int main()
{
cin >> N;
setboard();
printboard();
return 0;
}