🙇‍♀️연습문제(달팽이)

숫자를 입력받으면 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;
}

태그:

카테고리:

업데이트: