안녕하세요.

여행벌입니다.

오늘은 백준 사이트 2668번 '숫자고르기' 문제를 다뤄보겠습니다.

정보올림피아드 초등부 문제로 DFS 탐색을 이용해서 구현할 수 있었습니다.


[알고리즘설계]

1. 입력된 정수를 list에 담고 앞에서부터 다음과 같이 탐색을 진행한다.

- 아직 방문하지않은 점이라면 Cycle이 형성되거나 이미 탐색한 점이 나올때까지 탐색을 진행한다.

 -> Cycle이 형성되었다면, Cycle의 크기만큼 Count 해주고, Cycle에 속한 숫자들을 Answer_list에 담아준다.

( Cycle의 형성 유무는 탐색을 하며 지나왔던 숫자와 다음에 가야할 숫자를 비교하며 판단한다. )

 -> 이미 탐색한 점이 나왔다면, 기존에 탐색한 루트이므로 종료한다.

2. 모든 점에 대한 탐색이 끝났다면, Answer_list를 Sort 한 후 앞에서부터 출력해준다.

 

[예시]

Index [ 1 2 3 4 5 6 7 ]

Input [ 3 1 1 5 5 4 6 ]

1 -> 3 -> 1 (Cycle 형성, 1,3을 Answer_list에 담아준다.)

2 -> 1 ( 1은 이미 방문한 점이므로 탐색을 종료한다. )

3 ( 1에서 탐색을 진행할 때 이미 방문한 점이므로 탐색을 종료한다. )

4 -> 5 -> 5 (Cycle 형성, 5를 Answer_list에 담아준다.)

5 ( 4에서 탐색을 진행할 때 이미 방문한 점이므로 탐색을 종료한다. )

6 -> 4 ( 4는 이미 방문한 점이므로 탐색을 종료한다. )

7 -> 6 ( 6은 이미 방문한 점이므로 탐색을 종료한다.

 

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

int answer[100], nanswer = 0;
int list[101];
bool check[101];
int check_circle(int, int, int[]);
void circle(int);

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);
    
	int ninput;
	cin >> ninput;
	for (int i = 1; i <= ninput; i++)
		cin >> list[i];
        
	for (int i = 1; i <= ninput; i++) {
		if(check[i] == false) //방문하지않은점이라면 탐색 시작.
			circle(i);
	}
    
	cout << nanswer << '\n';
	sort(answer, answer + nanswer);
	for (int i = 0; i < nanswer; i++)
		cout << answer[i] << '\n';
}

int check_circle(int next, int count, int temp[]) {
	int i;
	for (i = count - 1; i >= 0; i--) {
		if (temp[i] == next) {
			return i;
		}
	}
	return -1;
}

void circle(int i) {
	int temp[100];
	int start = i;
	check[start] = true;
	int count = 0;
	temp[count++] = start;
	while (1) {
		int next = list[start];
		int ntemp = check_circle(next, count, temp);
		if (ntemp != -1) {
			for (int j = ntemp; j < count; j++) {
				answer[nanswer++] = temp[j];
			}
			return;
		}
        // 기존에 방문한 점이라면 종료.
		if (check[next] == true)
			return;
		start = next;
		check[start] = true;
		temp[count++] = start;
	}
}

초등부 문제라 입력은 작지만, 구현이 생각보다 까다로웠던 문제입니다. 

비슷한 문제로는 BOJ 9466번을 추천드립니다!


열심히 공부하고 노력하고 있는 꿈 많은 예비 개발자입니다.

혼자서 공부한 내용을 정리하고 포스팅하다 보니 틀린 내용이 있을 수도 있습니다.

많은 조언과 가르침 주실 분은 댓글로 자유롭게 남겨주셔도 좋을 것 같습니다! 

감사합니다.

'Problem Solving > BOJ' 카테고리의 다른 글

[BOJ] 1436 - 영화감독 숌  (0) 2019.08.21
[BOJ] 2456 - 나는 학습회장이다.  (0) 2019.08.21
[BOJ] 2579 - 계단 오르기  (0) 2019.08.21
[BOJ] 6603 - LOTTO  (0) 2019.08.21
[BOJ] 14503 - 로봇청소기  (0) 2019.08.16

안녕하세요.

여행벌입니다.

오늘은 백준사이트의 14503번 '로봇청소기' 문제 풀이를 해보겠습니다.


[문제해석]

한글 문제라 따로 다루지 않겠습니다.

 

[알고리즘설계]

1. 시작 점부터 반시계 방향으로 돌며 청소를 안 한 곳이 있으면 청소를 해나간다.

(청소를 하지 않은 곳은 0, 벽은 1, 청소를 한 곳은 2를 저장해나가며 청소를 진행한다.)

2. 모든 방향을 돌았는데, 갈 곳이 없다면 후진을 한다.

- 후진을 할 수 있으면 후진 후 다시 1번부터 진행.

- 후진을 할 수 없다면(뒤가 벽이라면) 종료한다.

#include<iostream>

using namespace std;

int map[50][50];
int dx[4] = { 0,-1,0,1 };
int dy[4] = { -1, 0, 1, 0 };

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int row, column;
	cin >> row >> column;
	int x, y, dir;
	// dir 0 북 1 동 2 남 3 서
	cin >> x >> y >> dir;
	for (int i = 0; i < row; i++)
		for (int j = 0; j < column; j++)
			cin >> map[i][j];

	int count = 0;
	int flag = 1; // 조건을 만족하면 0으로 바꾸고 while을끝낸다.
	while (flag) {
		if (!map[x][y])
			count++;
		map[x][y] = 2;
		for (int i = 0; i < 5; i++) {
			if (i == 4) { // 4바퀴를 다 돌았는데도 for문이 안깨짐 -> 후진하거나 멈춰야됨.
				int next_x = x + dx[(dir + 3) % 4];
				int next_y = y + dy[(dir + 3) % 4];
				if (0 <= next_x && next_x < row && 0 <= next_y && next_y < column && map[next_x][next_y] != 1) {
					x = next_x;
					y = next_y;
				}
				else
					flag = 0;
                break;
			}
			int next_x = x + dx[dir];
			int next_y = y + dy[dir];
			dir = (dir + 3) % 4;
			if (0 <= next_x && next_x < row && 0 <= next_y && next_y < column && !map[next_x][next_y]) {
				x = next_x;
				y = next_y;
				break;
			}
		}
	}
	cout << count;
}

[중요코드]

int dx[4] = {0,-1,0,1};
int dy[4] = {-1,0,1,0};

// 뒤로 후진해야하는경우.
int next_x = x + dx[(dir + 3) % 4];
int next_y = y + dy[(dir + 3) % 4];

// 왼쪽으로 반시계방향으로 도는 경우
int next_x = x + dx[dir];
int next_y = y + dy[dir];
dir = (dir + 3) % 4;

0(북), 1(동), 2(남), 3(서) 를 의미하고 우리는 반시계 방향(왼쪽)으로 회전하면서 청소할 공간이 있는지 찾아볼 것이다.

또, 모든 방향에 청소할 공간이 없다면 뒤로 후진을 해야 한다.

따라서 dx, dy 배열을 다음과 같이 선언하고 next_x, next_y를 위와 같이 다루면 깔끔하게 탐색을 진행할 수 있다.


dx, dy 배열을 선언하고 next_x, next_y 변수를 다루는데 미숙해 생각보다 구현하는데 오래 걸렸다.

 

열심히 공부하고 노력하고 있는 꿈 많은 예비 개발자입니다.
혼자서 공부한 내용을 정리하고 포스팅하다 보니 틀린 내용이 있을 수도 있습니다.
많은 조언과 가르침 주실 분은 댓글로 자유롭게 남겨주셔도 좋을 것 같습니다! 
감사합니다.

 

'Problem Solving > BOJ' 카테고리의 다른 글

[BOJ] 1436 - 영화감독 숌  (0) 2019.08.21
[BOJ] 2456 - 나는 학습회장이다.  (0) 2019.08.21
[BOJ] 2579 - 계단 오르기  (0) 2019.08.21
[BOJ] 6603 - LOTTO  (0) 2019.08.21
[BOJ] 2668 - 숫자고르기  (0) 2019.08.16

안녕하세요.

여행벌입니다.

오늘은 ACM-ICPC 2013 예선전 문제인 'KCPC' 풀이를 해보겠습니다.

단순 구현 문제로 문제 조건들만 잘 읽어준다면, 쉽게 풀 수 있습니다.


[문제해석]

1 ~ N 개의 팀이 있고, 1 ~ M 개의 문제가 있다고 하자.

문제마다 얻을 수 있는 점수는 0 ~ 100점이고, 팀 최종 점수는 모든 문제에서 획득한 점수의 합이라고 하자.

만약에 팀 최종 점수가 같다면 제출 횟수가 적은 팀이, 최종 점수와 제출 횟수고 같다면 마지막 제출이 더 빠른 팀이 이기고 동시에 서로 다른 팀이 문제를 제출하는 경우는 없다고 하자.

이때, 내가 속한 팀은 몇 등인지 출력하라.

 

[알고리즘설계]

Problem_Score[x][y] : x팀의 y번 문제에 대한 최대 점수.

total_socre[x] : x팀의 최종 점수.

count[x] : x팀의 문제 제출 횟수.

time[x] : x팀의 마지막 제출 시간.

위와 같은 배열을 4개 선언해주고 문제 해석에 맞춰서 구현을 진행하면 된다.

#include<iostream>

using namespace std;

int main(void){
	ios::sync_with_stdio(false);
	cin.tie(0);

	//freopen("input2.txt", "r", stdin);
	int test_case;
	cin >> test_case;
	for(int i = 0; i < test_case; i++){
		int nteams, nproblems, myid, nlog;
		cin >> nteams >> nproblems >> myid >> nlog;
		
		int team_problem[101][101]={};
		int count[101]={};
		int time[101]={};
		int total_score[101]={};

		for(int j = 1;j <= nlog; j++){
			int x,y,z;
			cin >> x >> y >> z;
			if (team_problem[x][y] < z)
				team_problem[x][y] = z;
			count[x]++;
			time[x] = j;
		}

		for (int j = 1; j <= nteams; j++){
			for (int k = 1; k <= nproblems; k++){
				total_score[j] += team_problem[j][k];
			}
		}

		int rank = 1;

		for (int j = 1; j <= nteams; j++){
			if(j == myid)
				continue;
			if(total_score[j] > total_score[myid])
				rank++;
			if(total_score[j] == total_score[myid]){
				if(count[j] < count[myid])
					rank++;
				if(count[j] == count[myid]){
					if(time[j] < time[myid])
						rank++;
				}
			}
		}
		cout << rank << '\n';

	}
}

열심히 공부하고 노력하고 있는 꿈 많은 예비 개발자입니다.
혼자서 공부한 내용을 정리하고 포스팅하다 보니 틀린 내용이 있을 수도 있습니다.
많은 조언과 가르침 주실 분은 댓글로 자유롭게 남겨주셔도 좋을 것 같습니다! 
감사합니다.

'Problem Solving > ICPC' 카테고리의 다른 글

[ACM-ICPC][BOJ] 10251 - Driving License  (0) 2019.08.27
[ACM-ICPC][BOJ] 9019 - DSLR  (0) 2019.08.16
[ACM-ICPC][BOJ] 7287 - Registration  (0) 2019.08.08
[ACM-ICPC][BOJ] 9011 - Order  (0) 2019.08.08
[ACM-ICPC][BOJ] 9012 - Parenthesis  (0) 2019.08.08

안녕하세요.

여행벌입니다.

ACM-ICPC 2013 예선전 문제인 'Registration' 을 다뤄보겠습니다.

네... 그냥 맞추라고 준 문제라 따로 설명없이 코드 올리겠습니다.


#include<stdio.h>

int main(void){
    printf("10\n");
    printf("travelbeeee");
}
열심히 공부하고 노력하고 있는 꿈 많은 예비 개발자입니다.
혼자서 공부한 내용을 정리하고 포스팅하다 보니 틀린 내용이 있을 수도 있습니다.
많은 조언과 가르침 주실 분은 댓글로 자유롭게 남겨주셔도 좋을 것 같습니다! 
감사합니다.

'Problem Solving > ICPC' 카테고리의 다른 글

[ACM-ICPC][BOJ] 9019 - DSLR  (0) 2019.08.16
[ACM-ICPC][BOJ] 3758 - KCPC  (0) 2019.08.09
[ACM-ICPC][BOJ] 9011 - Order  (0) 2019.08.08
[ACM-ICPC][BOJ] 9012 - Parenthesis  (0) 2019.08.08
[ACM-ICPC][BOJ] 9009 - Fibonacci Numbers  (0) 2019.08.05

+ Recent posts