문제 :

https://www.acmicpc.net/problem/2529

 

2529번: 부등호

두 종류의 부등호 기호 ‘<’와 ‘>’가 k개 나열된 순서열 A가 있다. 우리는 이 부등호 기호 앞뒤에 서로 다른 한 자릿수 숫자를 넣어서 모든 부등호 관계를 만족시키려고 한다. 예를 들어, 제시

www.acmicpc.net

#include <iostream>
#include <array>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

int K;
constexpr int MAX = 9;
constexpr int NUM_LENGTH_MAX = 10;
array<char, MAX + 1> inequality{ 0 };
array<int, NUM_LENGTH_MAX + 1> is_visited{ 0 };
vector<string> ans;

bool is_correct(string& temp)
{
	bool ret = true;
	for (int i = 0; i < K; i++) {
		if (inequality[i] == '<') {
			if (temp[i] >= temp[i + 1]) {
				return ret = false;
			}
		}
		else if (inequality[i] == '>') {
			if (temp[i] <= temp[i + 1]) {
				return ret = false;
			}
		}
	}

	return ret;
}

void Run(const int start_idx, const int depth, string temp)
{
	if (is_visited[start_idx]) {
		return;
	}

	is_visited[start_idx] = true;
	temp += to_string(start_idx);
	if (K == depth) {
		if (is_correct(temp)) {
			ans.push_back(temp);
		}

		is_visited[start_idx] = false;
		return;
	}

	for (int i = 0; i <= 9; i++) {
		Run(i, depth + 1, temp);
	}

	is_visited[start_idx] = false;
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> K;
	for (int i = 0; i < K; i++) {
		cin >> inequality[i];
	}

	for (int i = 0; i <= 9; i++) {
		Run(i, 0, "");
		memset(&is_visited, 0x00, sizeof(is_visited));
	}

	sort(ans.begin(), ans.end());

	cout << ans[ans.size() - 1] << '\n';
	cout << ans[0] << '\n';
	return 0;
}
  • 브루트포스 방법을 이용해 풀 수 있는 문제였습니다.
  • 재귀함수를 이용했습니다. 트리의 MAX 깊이가 10 이고, 모든 경우가 깊이 10까지 들어가지 않기 때문에 시간초과가 나지 않을 것이라고 생각했습니다.
  • 하지만 생각보다 elapsed time이 컸습니다. 방법을 수정해도 좋을것 같습니다.

'문제풀이 > 백준' 카테고리의 다른 글

12904 - A와 B  (0) 2023.05.21
15654 - N과 M (5)  (0) 2023.01.23
2636 - 치즈  (0) 2023.01.12
2661 - 좋은 수열  (0) 2023.01.08
2751 - 수 정렬하기 2  (0) 2023.01.06

https://www.acmicpc.net/problem/2636

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

#include <iostream>
#include <queue>
#include <array>
#include <cstring>
using namespace std;

int col, row;
constexpr int MAX = 100 + 1;
int cheese_map[MAX][MAX];
bool is_visited[MAX][MAX];
const array<int, 4> dx = { -1, 1, 0, 0 };
const array<int, 4> dy = { 0, 0, -1, 1 };
int cnt = 0;
int final_cnt = 0;

namespace curr_state {
	const enum { CHEESE = 1, READY_MELTED, AIR };
}

void change_cheese_to_air()
{
	for (int i = 1; i <= row; i++) {
		for (int j = 1; j <= col; j++) {
			if (cheese_map[i][j] == curr_state::READY_MELTED) {
				cheese_map[i][j] = curr_state::AIR;
			}
		}
	}
}

void search_air()
{
	memset(is_visited, 0, sizeof(is_visited));

	queue<pair<int, int>> air_idx;
	air_idx.push({ 1,1 });
	while (!air_idx.empty()) {
		const int current_air_x_idx = air_idx.front().first;
		const int current_air_y_idx = air_idx.front().second;
		air_idx.pop();
		for (int i = 0; i < dx.size(); i++) {
			const int next_x = current_air_x_idx + dx[i];
			const int next_y = current_air_y_idx + dy[i];
			if (next_x < 1 || next_x > row || next_y < 1 || next_y > col) {
				continue;
			}

			if (is_visited[next_x][next_y]) {
				continue;
			}

			if (!cheese_map[next_x][next_y] || cheese_map[next_x][next_y] == curr_state::AIR) {
				air_idx.push({ next_x, next_y });
				cheese_map[next_x][next_y] = curr_state::AIR;
				is_visited[next_x][next_y] = true;
			}
		}
	}
}

void search_melted_cheese()
{
	memset(is_visited, 0, sizeof(is_visited));

	queue<pair<int, int>> to_be_melted_cheese;
	to_be_melted_cheese.push({ 1,1 });
	while (!to_be_melted_cheese.empty()) {
		const int current_air_x_idx = to_be_melted_cheese.front().first;
		const int current_air_y_idx = to_be_melted_cheese.front().second;
		to_be_melted_cheese.pop();
		for (int i = 0; i < dx.size(); i++) {
			const int next_x = current_air_x_idx + dx[i];
			const int next_y = current_air_y_idx + dy[i];
			if (next_x < 1 || next_x > row || next_y < 1 || next_y > col) {
				continue;
			}

			if (is_visited[next_x][next_y]) {
				continue;
			}

			if (curr_state::AIR == cheese_map[next_x][next_y]) {
				to_be_melted_cheese.push({ next_x, next_y });
				is_visited[next_x][next_y] = true;
			}

			if (cheese_map[current_air_x_idx][current_air_y_idx] == curr_state::AIR &&
				cheese_map[next_x][next_y] == curr_state::CHEESE) {
				cheese_map[next_x][next_y] = curr_state::READY_MELTED;
				to_be_melted_cheese.push({ next_x, next_y });
				is_visited[next_x][next_y] = true;
			}
		}
	}
}

bool is_clear_all()
{
	int remain_cnt = 0;
	for (int i = 1; i <= row; i++) {
		for (int j = 1; j <= col; j++) {
			if (curr_state::CHEESE == cheese_map[i][j]) {
				remain_cnt++;
			}
		}
	}

	if (remain_cnt) {
		final_cnt = remain_cnt;
		return false;
	}

	return true;
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	cin >> row >> col;
	for (int i = 1; i <= row; i++) {
		for (int j = 1; j <= col; j++) {
			cin >> cheese_map[i][j];
		}
	}

	int cnt = 0;
	while (!is_clear_all()) {
		cnt++;
		search_air();
		search_melted_cheese();
		change_cheese_to_air();
	}
	
	cout << cnt << '\n';
	cout << final_cnt << '\n';

	return 0;
}

** C++ 17 Clang으로 제출합니다. 그렇지 않으면 다음 구문에서 컴파일 에러가 발생합니다.

namespace curr_state {
	const enum { CHEESE = 1, READY_MELTED, AIR };
}

 

'문제풀이 > 백준' 카테고리의 다른 글

15654 - N과 M (5)  (0) 2023.01.23
2529 - 부등호  (0) 2023.01.17
2661 - 좋은 수열  (0) 2023.01.08
2751 - 수 정렬하기 2  (0) 2023.01.06
1920 - 수 찾기  (2) 2023.01.05

문제 : https://www.acmicpc.net/problem/2580

 

2580번: 스도쿠

스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루

www.acmicpc.net

#include <iostream>
#include <vector>
using namespace std;
const int MAX = 9;
int sudoku[MAX][MAX];
bool row[MAX][MAX + 1]; //열, 1~9
bool col[MAX][MAX + 1]; //행, 1~9
bool square[MAX][MAX + 1]; //3*3 박스 idx, 1~9

int change2SquareIdx(int y, int x) // small square
{
	return (y / 3) * 3 + x / 3;
}

void DFS(int cnt)
{
	if (cnt == 81) {//Sudoku는 총 81칸
		for (int i = 0; i < MAX; i++) {
			for (int j = 0; j < MAX; j++)
				cout << sudoku[i][j] << " ";
			cout << endl;
		}
		exit(0); //답을 하나만 출력
	}

	int y = cnt / 9;
	int x = cnt % 9;
	if (sudoku[y][x]) //칸이 채워져있으면
		DFS(cnt + 1);
	else { //채워져있지 않았고	
		for (int k = 1; k <= MAX; k++) {
			//sudoku 규칙에 적합하면 채우고 본다
			if (!col[x][k] && !row[y][k] && !square[change2SquareIdx(y, x)][k]) {
				sudoku[y][x] = k;
				col[x][k] = true;
				row[y][k] = true;
				square[change2SquareIdx(y, x)][k] = true;
				DFS(cnt + 1);
				sudoku[y][x] = 0;
				col[x][k] = false;
				row[y][k] = false;
				square[change2SquareIdx(y, x)][k] = false;
			}
		}
	}
}

int main(void)
{
	for (int i = 0; i < MAX; i++) {
		for (int j = 0; j < MAX; j++) {
			cin >> sudoku[i][j];
			if (sudoku[i][j]) {
				col[j][sudoku[i][j]] = true;							// j열에 sudoku[i][j] 체크
				row[i][sudoku[i][j]] = true;							// i행에 sudoku[i][j] 체크 
				square[change2SquareIdx(i, j)][sudoku[i][j]] = true;	// 작은 사각형의 체크
			}
		}
	}

	DFS(0); //sudoku는 81칸
	return 0;
}

참고 : https://jaimemin.tistory.com/664

 

백준 2580번 스도쿠

문제 링크입니다: https://www.acmicpc.net/problem/2580 흥미로운 백트래킹 문제였습니다.처음에 풀 때는 3*3 칸 내에서도 1~9가 하나씩 존재해야한다는 규칙을 잊어먹어서 틀렸습니다.3*3 칸 내 인덱스는 ch

jaimemin.tistory.com

  • 재귀함수를 이용해 조건에 맞을 경우, 순차적으로 스도쿠에 수를 채우는문제였습니다.
  • 입력을 받을때가 중요합니다.
  • 예를 들어 아래와 같이 처리합니다.
  • col[j][sudoku[i][j]] = true; // j열에 sudoku[i][j] 체크

row[i][sudoku[i][j]] = true; // i행에 sudoku[i][j] 체크

square[change2SquareIdx(i, j)][sudoku[i][j]] = true; // 작은 사각형의 체크

한 입력이 들어올때, 이것은 9*9 스도쿠에서의 한 열과 한 행에 두 가지 경우에 대해서 모두 공통적으로 입력되는 것입니다.

그렇기 때문에 sudoku[i][j] 입력이 있을때, 이 수를 col[j][sudoku[i][j], row[i][sudoku[i][j]]에 대해서 true, false 처리해줍니다.

  • 또 중요한 것이 작은 사각형 3*3을 처리하는 것입니다. 이것은 int change2SquareIdx(int y, int x) 함수로 좌표를 변환해줍니다.
  • 이와 비슷한 문제가 있는것으로 복습을 해야겠네요.

1. 삼각형 무게 중심

2. 벡터의 내적, 외적, 넓이

3. 삼각함수

4. 다항함수의 그래프

 

ebsi에서 모두 학습 가능

https://www.acmicpc.net/problem/2661

 

2661번: 좋은수열

첫 번째 줄에 1, 2, 3으로만 이루어져 있는 길이가 N인 좋은 수열들 중에서 가장 작은 수를 나타내는 수열만 출력한다. 수열을 이루는 1, 2, 3들 사이에는 빈칸을 두지 않는다.

www.acmicpc.net

#include <iostream>
#include <string>
using namespace std;

int N;
string num;

void permutation(const char c, const int cnt)
{
    //조건 만족(제일 먼저 나오는 숫자가 제일 작은 수)

    if (cnt - 1 == N) {
        cout << num << "\n";
        exit(0);
    }

    num += c;

    for (int i = 1; i <= cnt / 2; i++) {
        const string&& a = num.substr(cnt - i, i);
        const string&& b = num.substr(cnt - i * 2, i);
        //나쁜 수열

        if (a == b) {
            num.erase(cnt - 1);
            return;
        }
    }

    for (int i = 1; i <= 3; i++) {
        permutation(i + '0', cnt + 1);
    }

    num.erase(cnt - 1);  //cnt - 1 자리가 성립하지 않을 경우
}

int main(void)
{
    cin >> N;
    for (int i = 1; i <= 3; i++) {
        permutation(i + '0', 1);
    }

    return 0;
}
 

재귀함수를 이용하여 풀 수있는 문제였습니다. 코드는 위 링크와 완전 동일합니다.

기본적으로 아래와 같은 방법으로 주어진 자리수의 숫자를 체크합니다.

  • 재귀함수를 이용하여 1 + 1 + 1 -> '111' 과 같은 방법으로 모든 숫자를 점검하는 컨셉입니다.
  • 하지만 실제로 모든 경우를 체크해볼 필요는 없습니다. 이유는 아래와 같습니다.
  • 1 + 1 + 1 이런식으로 체크하기 때문에, 가장 낮은수부터 체크하게끔 돼있습니다.
  • 그렇기 때문에, 만일 조건이 충족되는 최초의 숫자가 발견된다면, 그 즉시 프로그램 종료하면 됩니다. 그 숫자가 가장 작기 때문입니다.

위 사진과 같이 재귀함수를 이용해 각각의 case를 검사합니다.

 

'문제풀이 > 백준' 카테고리의 다른 글

2529 - 부등호  (0) 2023.01.17
2636 - 치즈  (0) 2023.01.12
2751 - 수 정렬하기 2  (0) 2023.01.06
1920 - 수 찾기  (2) 2023.01.05
5430 - AC  (0) 2023.01.05
#include <iostream>
#include <algorithm>
#include <array>
using namespace std;

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int N;
	cin >> N;
	const int MAX_CNT = 1000000;
	array<int, MAX_CNT> my_arr;
	for (int i = 0; i < N; i++) {
		int num;
		cin >> num;
		my_arr[i] = num;
	}

	sort(my_arr.begin(), my_arr.begin() + N);

	for (int i = 0; i < N; i++) {
		cout << my_arr[i] << '\n';
	}

	return 0;
}

 

std sort를 이용하면 쉽게 풀 수 있는 문제였습니다.

'문제풀이 > 백준' 카테고리의 다른 글

2636 - 치즈  (0) 2023.01.12
2661 - 좋은 수열  (0) 2023.01.08
1920 - 수 찾기  (2) 2023.01.05
5430 - AC  (0) 2023.01.05
6603 - 로또  (0) 2023.01.03

https://www.acmicpc.net/problem/2750

 

2750번: 수 정렬하기

첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 절댓값이 1,000보다 작거나 같은 정수이다. 수는 중복되지 않는다.

www.acmicpc.net

N = int(input())
arr = [0 for i in range(N)]

for i in range(0, N):
    num = int(input())
    arr[i] = num

arr.sort()
for i in range(N):

    print(arr[i])

1초라는 시간 제한을 고려했을때, 내장 sort를 이용하면 쉽게 풀 수 있을것이라 생각했고 , 실제로 무난하게 통과했습니다.

'문제풀이' 카테고리의 다른 글

3009 - 네 번째 점  (0) 2021.09.11
#include <iostream>
#include <GL/glut.h>

void display()
{
	glClearColor(1.0f, 0.25f, 1.0f, 1.0f); // 배경 color 지정
	glClear(GL_COLOR_BUFFER_BIT);		   // 지정한 color로 배경 초기화
	
	glColor3f(0.5f, 0.25f, 0.68f);		   // 도형색 지정
	glBegin(GL_TRIANGLES);				   // 도형 타입 선언
	glVertex2f(-0.5f, -0.2f);				// 도형 좌표 선언
	glVertex2f(0.4f, -0.4f);
	glVertex2f(-0.97f, 0.2f);
	glEnd();

	glFinish();
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutCreateWindow("OpenGL");
	glutDisplayFunc(display);
	glutMainLoop();
	return 0;
}

삼각형을 그려봤습니다 ㅎㅎ.

opengl은 visual studio 셋업하는것만 해도 너무 귀찮네요.... ㅜ vcpkg로 freeglut같은 경우는 사용할 수 없는것 같아요.

위와 같은 삼각형 이미지가 출력됩니다.

좌표를 확인해보니, OpenGL은 이미지좌표계가 아닌 일반 xy cartesian coordinate을 이용하는 것 같습니다.

 

'그래픽스 > OpenGL' 카테고리의 다른 글

LearnOpenGL - Introduction  (0) 2023.01.23
LearnOpenGL 번역  (0) 2023.01.23
OpenGL glVertex2f()  (0) 2022.07.27
파이썬 opengl 패키지 설치  (0) 2022.07.12

+ Recent posts