728x90

www.acmicpc.net/problem/16234

 

16234번: 인구 이동

N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모

www.acmicpc.net

DFS로 풀었다. BFS나 DFS나 아무거나로 풀어도 된다.

DFS는 연합을 만드는 과정이다. 상하좌우 탐색하면서 l개 이상 r개 이하로 차이가 나면 스택에 넣어주었다.

탐색을 하면서 그 연합에 속하는 나라의 행과 열을 pair로 묶어서 countries라는 벡터에 넣어줬다.

또한 그 연합에 속하는 나라의 인구 수를 sum에 누적해서 더해줬다.

그렇게 연합을 만든 후에 sum을 countries.size()로 나눠서 인구 수를 갱신해주었다.

countries.size()가 1이면 인구 이동이 일어나지 않는 것이고 1보다 크면 인구 이동이 일어났다는 것이므로 flag = true로 해준다.

flag가 false라는 것은 더 이상 인구 이동이 일어나지 않는다는 것이므로 while문을 빠져나온다.

가장 바깥쪽 while문은 인구이동이 몇 번 일어났는지를 세어준다.

#include <iostream>
#include <vector>
#include <stack>
#include <cmath>
using namespace std;

int main() {
	cin.tie(NULL);
	ios::sync_with_stdio(false);
	int n, l, r;
	cin >> n >> l >> r;
	vector<vector<int>> v(n, vector<int>(n));
	vector<vector<bool>> visited(n, vector<bool>(n, false));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> v[i][j];
		}
	}
	int moveCount = 0;
	while (true) {
		visited = vector<vector<bool>>(n, vector<bool>(n, false));
		bool flag = false;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (!visited[i][j]) {
					stack<pair<int, int>> stack;
					stack.push(make_pair(i, j));
					int sum = 0;
					vector<pair<int, int>> countries;
					while (!stack.empty()) {
						pair<int, int> cur = stack.top();
						stack.pop();
						int row = cur.first;
						int col = cur.second;
						if (!visited[row][col]) {
							visited[row][col] = true;
							sum += v[row][col];
							countries.push_back(cur);
							if (row + 1 < n && abs(v[row][col] - v[row + 1][col]) >= l && abs(v[row][col] - v[row + 1][col]) <= r) {
								stack.push(make_pair(row + 1, col));
							}
							if (row - 1 >= 0 && abs(v[row][col] - v[row - 1][col]) >= l && abs(v[row][col] - v[row - 1][col]) <= r) {
								stack.push(make_pair(row - 1, col));
							}
							if (col + 1 < n && abs(v[row][col] - v[row][col + 1]) >= l && abs(v[row][col] - v[row][col + 1]) <= r) {
								stack.push(make_pair(row, col + 1));
							}
							if (col - 1 >= 0 && abs(v[row][col] - v[row][col - 1]) >= l && abs(v[row][col] - v[row][col - 1]) <= r) {
								stack.push(make_pair(row, col - 1));
							}
						}
					}
					if (countries.size() > 1) {
						flag = true;
						for (int k = 0; k < countries.size(); k++) {
							int row = countries[k].first;
							int col = countries[k].second;
							v[row][col] = sum / countries.size();
						}
					}
				}
			}
		}
		if (!flag)
			break;
		moveCount++;
	}
	cout << moveCount;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 13460번 구슬 탈출 2  (0) 2021.01.20
[백준] 2458번 키 순서  (0) 2021.01.19
[백준] 1339번 단어 수학  (0) 2021.01.18
[백준] 5014번 스타트링크  (0) 2021.01.18
[백준] 12100번 2048 (Easy)  (0) 2021.01.18
728x90

삼성 SW 역량 테스트 기출 문제인 14503번 문제

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 벽 또는 빈 칸이다. 청소기는 바라보는 방향이 있으며, 이 방향은 동, 서, 남, 북중 하나이다. 지도의 각 칸은 (r, c)로 나타낼 수 있고, r은 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로 부터 떨어진 칸의 개수이다. 로봇 청소기는 다음

www.acmicpc.net

문제를 그대로 코드로 구현하면 되는 직관적인 문제였다.

def clean(now_row, now_col, direction):
    if li[now_row][now_col] == 0:
        li[now_row][now_col] = 2 #2는 청소된 부분을 말한다
    if li[now_row][now_col - 1] != 0 and li[now_row - 1][now_col] != 0 and li[now_row][now_col + 1] != 0 and li[now_row + 1][now_col] != 0:
        if direction == 0 and li[now_row + 1][now_col] != 1:
            clean(now_row + 1, now_col, direction)
        elif direction == 1 and li[now_row][now_col - 1] != 1:
            clean(now_row, now_col - 1, direction)
        elif direction == 2 and li[now_row - 1][now_col] != 1:
            clean(now_row - 1, now_col, direction)
        elif direction == 3 and li[now_row][now_col + 1] != 1:
            clean(now_row, now_col + 1, direction)
        else:
            return
    elif direction == 0:
        if li[now_row][now_col - 1] == 0:
            clean(now_row, now_col - 1, 3)
        else:
            clean(now_row, now_col, 3)
    elif direction == 1:
        if li[now_row - 1][now_col] == 0:
            clean(now_row - 1, now_col, 0)
        else:
            clean(now_row, now_col, 0)
    elif direction == 2:
        if li[now_row][now_col + 1] == 0:
            clean(now_row, now_col + 1, 1)
        else:
            clean(now_row, now_col, 1)
    elif direction == 3:
        if li[now_row + 1][now_col] == 0:
            clean(now_row + 1, now_col, 2)
        else:
            clean(now_row, now_col, 2)
from sys import stdin
n, m = list(map(int, stdin.readline().split()))
r, c, d = list(map(int, stdin.readline().split()))
li = []
visited = [[False] * m for i in range(n)]
for i in range(n):
    li.append(list(map(int, stdin.readline().split())))
clean(r, c, d)
count = 0
for i in range(n):
    for j in range(m):
        if li[i][j] == 2:
            count += 1
print(count)
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1932번 정수 삼각형  (0) 2020.01.18
[백준] 14890번 경사로  (0) 2020.01.16
[백준] 1149번 RGB 거리  (0) 2020.01.12
[백준] 9461번 파도반수열  (0) 2020.01.12
[백준] 11729번 하노이 탑 이동 순서  (0) 2020.01.12
728x90

단계별로 풀어보기 DFS와 BFS의 4단계 문제이다

 

 

1012번: 유기농 배추

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추흰지렁이를 구입하기로 결심한다. 이 지렁이는 배추근처에 서식하며 해충을 잡아 먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. (

www.acmicpc.net

3단계 문제인 2667번과 입출력 방법 말고는 거의 같아서 쉽게 풀 수 있었다.

오히려 배추 개수를 출력할 필요가 없어서 더 쉬웠다.

def dfs(row, col):
    if li[row][col] == 0 or visited[row][col]:
        return 0
    stack = []
    stack.append((row, col))
    while stack:
        cur = stack.pop()
        visited[cur[0]][cur[1]] = True
        if li[cur[0] - 1][cur[1]] == 1 and not visited[cur[0] - 1][cur[1]]:
            if 1 <= cur[0] - 1 <= n and 1 <= cur[1] <= m:
                stack.append((cur[0] - 1, cur[1]))
        if li[cur[0] + 1][cur[1]] == 1 and not visited[cur[0] + 1][cur[1]]:
            if 1 <= cur[0] + 1 <= n and 1 <= cur[1] <= m:
                stack.append((cur[0] + 1, cur[1]))
        if li[cur[0]][cur[1] - 1] == 1 and not visited[cur[0]][cur[1] - 1]:
            if 1 <= cur[0] <= n and 1 <= cur[1] - 1 <= m:
                stack.append((cur[0], cur[1] - 1))
        if li[cur[0]][cur[1] + 1] == 1 and not visited[cur[0]][cur[1] + 1]:
            if 1 <= cur[0] <= n and 1 <= cur[1] + 1 <= m:
                stack.append((cur[0], cur[1] + 1))
    return 1

test_case = int(input())
from sys import stdin

for i in range(test_case):
    m, n, k = list(map(int, stdin.readline().split()))
    li = [[0] * m for j in range(n)]
    for j in range(0, k):
        rawInput = list(map(int, stdin.readline().split()))
        li[rawInput[1]][rawInput[0]] = 1
    li.insert(0, [0] * (m + 2))
    li.append([0] * (m + 2))
    for j in range(1, n + 1):
        li[j].insert(0, 0)
    for j in range(1, n + 1):
        li[j].append(0)
    visited = [[False for j in range(m + 2)] for i in range(n + 2)]
    count = 0
    for j in range(1, n + 1):
        for l in range(1, m + 1):
            count += dfs(j, l)
    print(count)


728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 11399 ATM  (0) 2020.01.10
[백준] 11047 동전0  (0) 2020.01.10
[백준] 2667번 단지번호붙이기  (0) 2020.01.08
[백준] 2606번 바이러스  (0) 2020.01.08
[백준] 1260번 DFS와 BFS  (0) 2020.01.08
728x90

단계별로 풀어보기 DFS와 BFS의 2단계 문제

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어진다. 이어서 그 수만큼 한 줄에 한 쌍씩 네트워크 상에서 직접 연결되어 있는 컴퓨터의 번호 쌍이 주어진다.

www.acmicpc.net

파이썬과 C++로 풀어보았다.

파이썬 코드

class Graph:
    def __init__(self, n):
        self.data = {}
        for i in range(1, n + 1):
            self.data[i] = set()
    def add_edge(self, n, m):
        self.data[n].add(m)
        self.data[m].add(n)
    def dfs(self, start):
        count = 0
        visited = [False] * (len(self.data) + 1)
        stack = []
        stack.append(start)
        while stack:
            cur = stack.pop()
            if not visited[cur]:
                count += 1
            visited[cur] = True
            temp = []
            for i in self.data[cur]:
                if not visited[i]:
                    temp.append(i)
            temp.sort()
            temp.reverse()
            stack.extend(temp)
        print(count - 1)

from sys import stdin

nodeCount = int(input())
edgeCount = int(input())
graph = Graph(nodeCount)
li = []
for i in range(0, edgeCount):
    rawInput = list(map(int, stdin.readline().split()))
    graph.add_edge(rawInput[0], rawInput[1])
graph.dfs(1)

C++ 코드

#include <iostream>
#include <tuple>
#include <queue>
#include <vector>
using namespace std;

vector<int> w[101];
vector<bool> visited(101);


int main() {
	int numOfComputers;
	cin >> numOfComputers;
	int numOfEdge;
	cin >> numOfEdge;
	for (int i = 0; i < numOfEdge; i++) {
		int n, m;
		cin >> n >> m;
		w[n].push_back(m);
		w[m].push_back(n);
	}
	queue<int> q;
	q.push(1);
	while (!q.empty()) {
		int cur = q.front();
		q.pop();
		if (!visited[cur]) {
			visited[cur] = true;
			for (int i : w[cur]) {
				q.push(i);
			}
		}
	}
	int count = 0;
	for (int i = 1; i <= numOfComputers; i++) {
		if (visited[i]) count++;
	}
	cout << count - 1;
	return 0;
}

2월 4일에 이렇게 풀고 두 달 뒤인 4월 7일에 C++로 다시 풀어보았다.

#include <iostream>
#include <vector>
#include <stack>
using namespace std;


int main() {
	int numOfComputers, n;
	cin >> numOfComputers >> n;
	vector<int> v[101];
	vector<bool> visited(numOfComputers + 1);
	for (int i = 0; i < n; i++) {
		int from, to;
		cin >> from >> to;
		v[from].push_back(to);
		v[to].push_back(from);
	}
	stack<int> s;
	s.push(1);
	while (!s.empty()) {
		int cur = s.top();
		s.pop();
		visited[cur] = true;
		for (int i = 0; i < v[cur].size(); i++) {
			if (!visited[v[cur][i]]) {
				s.push(v[cur][i]);
			}
		}
	}
	int cnt = 0;
	for (int i = 2; i <= numOfComputers; i++) {
		if (visited[i] == true)
			cnt++;
	}
	cout << cnt;
	return 0;
}

이번에는 DFS로 풀어보았다. 막 다른 길이 나왔을 때 가지치기를 빨리 하라고 DFS를 쓰긴 했는데 DFS를 쓰나 BFS를 쓰나 별 차이는 없을 것 같다.

이 문제는 가중치가 없는 무방향 그래프에서 1부터 탐색을 하면 된다. 그렇게 방문된 노드의 수에서 1을 빼면 그게 바이러스에 걸린 컴퓨터 대수이다. 바이러스든 뭐든 퍼트리는 것은 다 DFS, BFS라고 생각하면 된다.

그래프를 저장하는 방법은 벡터를 사용했다. 벡터의 배열을 사용해서 노드 i와 연결된 노드들은 v[i] 벡터에 push_back 해줘서 차곡차곡 넣어주었다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1012 유기농 배추  (0) 2020.01.08
[백준] 2667번 단지번호붙이기  (0) 2020.01.08
[백준] 1260번 DFS와 BFS  (0) 2020.01.08
[백준] 1912 연속합 (미해결)  (0) 2020.01.07
[백준] 9963번 N-Queen  (0) 2020.01.06
728x90

단계별로 풀어보기 DFS와 BFS의 1단계 문제

 

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

www.acmicpc.net

이번에는 파이썬으로 풀어봤다.

class Graph:
    def __init__(self, n):
        self.data = {}
        for i in range(1, n + 1):
            self.data[i] = set()
    def add_edge(self, n, m):
        self.data[n].add(m)
        self.data[m].add(n)
    def dfs(self, start):
        visited = [False] * (len(self.data) + 1)
        stack = []
        stack.append(start)
        while stack:
            cur = stack.pop()
            if not visited[cur]:
                print(cur, end=" ")
            visited[cur] = True
            temp = []
            for i in self.data[cur]:
                if not visited[i]:
                    temp.append(i)
            temp.sort()
            temp.reverse()
            stack.extend(temp)
    def bfs(self, start):
        import collections
        visited = [False] * (len(self.data) + 1)
        queue = collections.deque()
        queue.append(start)
        while queue:
            cur = queue.popleft()
            if not visited[cur]:
                print(cur, end=' ')
            visited[cur] = True
            temp = []
            for i in self.data[cur]:
                if not visited[i]:
                    temp.append(i)
            temp.sort()
            queue.extend(temp)
from sys import stdin

node_edge_start = list(map(int, stdin.readline().split()))
graph = Graph(node_edge_start[0])
li = []
for i in range(0, node_edge_start[1]):
    rawInput = list(map(int, stdin.readline().split()))
    graph.add_edge(rawInput[0], rawInput[1])
graph.dfs(node_edge_start[2])
print()
graph.bfs(node_edge_start[2])

 

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2667번 단지번호붙이기  (0) 2020.01.08
[백준] 2606번 바이러스  (0) 2020.01.08
[백준] 1912 연속합 (미해결)  (0) 2020.01.07
[백준] 9963번 N-Queen  (0) 2020.01.06
[백준] 15652번 N과 M (4)  (0) 2020.01.06
728x90

단계별로 풀어보기 백트래킹의 5단계 문제

그 유명한 N-Queens Problem이다.

 

9663번: N-Queen

N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

이번학기 알고리즘 시간에 정말 잘 배운 문제라 쉽게 풀 수 있었다.

import java.util.Scanner;

public class Main {
    static int count = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] col = new int[n];
        queen(col, n, 0);
        System.out.println(count);
    }

    static void queen(int[] col, int n, int num) {
        if (num == n) {
            count++;
            return;
        }
        for (int i = 0; i < n; i++) {
            if (promising(col, num, i)) {
                 col[num] = i;
                 queen(col, n, num + 1);
                 col[num] = 0;
            }
        }
    }
    static boolean promising(int[] col, int r, int c) {
        for (int i = 0; i < r; i++) {
            if(col[i] == c || Math.abs(c - col[i]) == Math.abs(r - i)) {
                return false;
            }
        }
        return true;
    }
}

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1260번 DFS와 BFS  (0) 2020.01.08
[백준] 1912 연속합 (미해결)  (0) 2020.01.07
[백준] 15652번 N과 M (4)  (0) 2020.01.06
[백준] 15651 N과 M (3)  (0) 2020.01.06
[백준] 15650번 N과 M (2)  (0) 2020.01.06
728x90

n, k를 입력받아 nCk의 모든 경우를 출력하는 코드이다.

import java.util.Scanner;

public class Combination {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        boolean[] visited = new boolean[n];
        for (int i = 0; i < n; i++) {
            visited[i] = false;
        }
        int[] result = new int[k];
        combination(visited, n, k, 0, result);
    }

    static void combination(boolean[] visited, int n, int k, int num, int[] result) {
        if (num == k) {
            for (int i = 0; i < k; i++) {
                System.out.print(result[i] + " ");
            }
            System.out.println();
            return;
        }
        for (int i = 0; i < n; i++) {
            if(!visited[i]) {
                if (num > 0) {
                    if (result[num - 1] < i + 1) {
                        visited[i] = true;
                        result[num] = i + 1;
                    }
                    else continue;
                }
                else {
                    visited[i] = true;
                    result[num] = i + 1;
                }
                combination(visited, n, k, num + 1, result);
                visited[i] = false;
            }
        }
    }
}

 

728x90

'알고리즘' 카테고리의 다른 글

[알고리즘] 플로이드 (Floyd) 알고리즘  (0) 2020.02.08
[알고리즘] 순열 (Permutation)  (0) 2020.01.06
728x90

nPr의 모든 경우를 출력하는 코드이다.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(); //1부터 n까지의 숫자 중에서
        int r = in.nextInt(); //r개를 뽑는다
        boolean[] visited = new boolean[n];
        int[] selected = new int[r];
        for (int i = 0; i < n; i++) {
            visited[i] = false;
        }
        permutation(selected, visited, n, r, 0);
    }
    static void permutation(int[] selected, boolean[] visited, int n, int r, int num) {
        if (num == r) {
            for (int i = 0; i < r; i++) {
                System.out.print(selected[i] + " ");
            }
            System.out.println();
            return;
        }
        for (int i = 0; i < n; i++) {
            if(!visited[i]){
                visited[i] = true;
                selected[num] = i + 1;
                permutation(selected, visited, n, r, num + 1);
                visited[i] = false;
            }
        }
    }
}

permutation 함수의 매개변수인 num은 num번째 숫자를 정하는 것이다.

permutation 함수의 for문은 그 num번째 자리에 1부터 n까지의 숫자 중에 어떤 숫자를 넣을지 정하는 것이다.

728x90

'알고리즘' 카테고리의 다른 글

[알고리즘] 플로이드 (Floyd) 알고리즘  (0) 2020.02.08
[알고리즘] 조합 (Combination)  (0) 2020.01.06
728x90

단계별로 풀어보기 동적계획법1의 마지막 단계 (14단계) 12865문제

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)가 주어진다. 입력으로 주어지는 모든 수는 정수이다.

www.acmicpc.net

그 유명한 0/1 Knapsack 문제이다.

이번학기 알고리즘 수업 시간에 아주 많이 다룬 문제라서 쉽게 풀 수 있었다.

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int maxWeight = in.nextInt();
        int[] weight = new int[n];
        int[] value = new int[n];
        for (int i = 0; i < 2 * n; i++) {
            if(i % 2 == 0) weight[i / 2] = in.nextInt();
            else value[i / 2] = in.nextInt();
        }
        int[][] arr = new int[n + 1][maxWeight + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= maxWeight; j++) {
                if (i == 0 || j == 0) {
                    arr[i][j] = 0;
                } else if (weight[i - 1] <= j) {
                    arr[i][j] = Integer.max(arr[i - 1][j], value[i - 1] + arr[i - 1][j - weight[i - 1]]);
                }
                else {
                    arr[i][j] = arr[i - 1][j];
                }
            }
        }
        System.out.println(arr[n][maxWeight]);
    }
}

 

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 15649번 N과 M (1)  (0) 2020.01.06
[백준] 14502번 연구소  (0) 2020.01.05
[백준] 9251번 LCS (Longest Common Sequence)  (0) 2020.01.04
[백준] 1904번 01타일  (0) 2020.01.04
[백준] 1003번 피보나치 함수  (0) 2020.01.04
728x90

백준 온라인 저지 단계별로 풀어보기 브루트포스 5단계 문제 1486번

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

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < 3000000; i++) {
            if(String.valueOf(i).contains("666"))
                list.add(i);
        }
        System.out.println(list.get(n - 1));
    }
}

처음에는

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String s = "666";
        HashSet set = new HashSet<>();
        for (int i = 0; i < 10000; i++) {
            if(String.valueOf(i).length() == 1) {
                set.add(Integer.parseInt(s + i));
                set.add(Integer.parseInt(i + s));
            } 
            else if (String.valueOf(i).length() == 2) {
                set.add(Integer.parseInt(s + i));
                set.add(Integer.parseInt(i + s));
                set.add(Integer.parseInt(String.valueOf(i).charAt(0) + s + String.valueOf(i).charAt(1)));
            }
            else if (String.valueOf(i).length() == 3) {
                set.add(Integer.parseInt(s + i));
                set.add(Integer.parseInt(i + s));
                set.add(Integer.parseInt(String.valueOf(i).charAt(0) + s + String.valueOf(i).substring(1, 3)));
                set.add(Integer.parseInt(String.valueOf(i).substring(0, 2) + s + String.valueOf(i).charAt(2)));
            }
            else {
                set.add(Integer.parseInt(s + i));
                set.add(Integer.parseInt(i + s));
                set.add(Integer.parseInt(String.valueOf(i).charAt(0) + s + String.valueOf(i).substring(1, 4)));
                set.add(Integer.parseInt(String.valueOf(i).substring(0, 2) + s + String.valueOf(i).substring(2, 4)));
                set.add(Integer.parseInt(String.valueOf(i).substring(0, 3) + s + String.valueOf(i).charAt(3)));
            }
        }
        ArrayList list = new ArrayList<>(set);
        list.sort((a, b) -> a - b);
        System.out.println(list.get(n - 1));
    }
}

이렇게 했는데 자꾸 틀렸다고 나오는거다.

그래서 포기하고 구글링을 해봤더니 자바의 String 클래스에 contains()라는 메소드가 있었다.

Java10 API String 클래스의 contains 메소드

https://docs.oracle.com/javase/10/docs/api/java/lang/String.html

 

String (Java SE 10 & JDK 10 )

Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argum

docs.oracle.com

이 메소드를 이용해서 0부터 (넉넉하게) 3000000까지 완전히 브루트포스한 방법으로 성공하긴 했는데 아까 그 코드가 왜 틀렸는지가 너무 궁금했다.

그래서 그 리스트를 다 출력해서 복사해서 워드에 붙여넣고 줄번호를 넣어서 비교해봤다.

 

확실히 결과가 다르긴 한데 어디서 부터 왜 잘못된건지 찾아보았다.

비교해보니 121번째 숫자부터 잘못되었다. 보니까 int를 String으로 변환한 후 그것을 concatenation했기 때문에 0이나 00이나 int로는 똑같은 0이기 때문에 00 같은 경우는 빠진 것이었다.

내가 처음에 한 방법은 0부터 큰 숫자를 찾은 것이 아니기 때문에 HashSet을 이용해서 유일하게 만든 후 그것을 ArrayList로 만들고 따로 정렬을 했지만 정답을 낸 이 방법은 정렬을 할 필요도 없었다.

물론 복잡도는 더 높겠지만 이 유형 자체가 브루트포스이기 때문에 무식하게 풀어도 시간초과가 나지 않았다.

728x90

+ Recent posts