Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions problems/SWEA/p1868/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* (1868) 파핑파핑 지뢰찾기
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5LwsHaD1MDFAXc&categoryId=AV5LwsHaD1MDFAXc&categoryType=CODE&problemTitle=1868&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

import java.io.*;
import java.util.*;

/**
* SW Expert Academy - 파핑파핑 지뢰찾기
* @author YeJun, Jung
*
* [분석]
* - 지뢰찾기 게임과 규칙은 동일하다.
* - 최소한의 클릭으로 지뢰가 없는 칸들을 모두 여는 방법을 찾아야 한다.
*
* [전략]
* - 각 칸은 ID를 가지고 있다.
* - 각 ID에 대해서 부모 노드의 ID를 보관하는 배열 parentArr가 있다.
* - 처음에 parentArr는 자기자신을 가르키도록 초기화 한다.
* - 각 칸(ID)에 대해서 DFS으로 칸을 열어본다.
* - 열어본 칸에 대해서는 ID로 기록을 한다.
* - 칸을 열때 다른 ID가 기록되어 있다면 해당 칸의 ID와 현재 ID를 Union 한다.
* - parentArr에 있는 ID 종류의 개수가 정답이 된다.
*/
public class Solution {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder output = new StringBuilder();
static StringTokenizer input;

// ----------------------------------------------------------

public static void main(String[] args) throws IOException {
final int testCount = nextInt();

for (int testCase = 1; testCase <= testCount; testCase++) {
new Solution(testCase).run();
}

System.out.print(output.toString());
}

// ----------------------------------------------------------

static final int[] DIR_X = { -1, 1, 0, 0, 1, 1, -1, -1 };
static final int[] DIR_Y = { 0, 0, -1, 1, 1, -1, 1, -1 };
static final int DIR_LEN = 8;

int testCase;
int answer;
int boardSize;
int[][] board;

int[] parentArr;

public Solution(int testCase) { this.testCase = testCase; }
public void run() throws IOException { input(); solve(); print(); }

private void input() throws IOException {
char[] buf;

boardSize = nextInt();
board = new int[boardSize][boardSize];

for (int y = 0; y < boardSize; y++) {
buf = next().toCharArray();

for (int x = 0; x < boardSize; x++) {
if (buf[x] == '.') continue;

board[y][x] = -1;
}
}
}

private void solve() {
answer = 0;

makeParentArr();

for (int y = 0; y < boardSize; y++) {
for (int x = 0; x < boardSize; x++) {
int id = (y * boardSize) + x + 1;

if (board[y][x] != 0) {
parentArr[id] = 0;
continue;
}

board[y][x] = id;
openTile(x, y, id);
}
}

updateAnswer();
}

private void makeParentArr() {
final int N = boardSize * boardSize + 1;
parentArr = new int[N];

for (int idx = 0; idx < N; idx++) {
parentArr[idx] = idx;
}
}

private int findParent(int idx) {
if (parentArr[idx] == idx) return idx;
return findParent(parentArr[idx]);
}

private void unionParent(int a, int b) {
int pa = findParent(a);
int pb = findParent(b);
if (pa != pb) parentArr[pb] = pa;
}

private void openTile(int x, int y, int id) {
int cnt = 0;

for (int dir = 0; dir < DIR_LEN; dir++) {
int nx = x + DIR_X[dir];
int ny = y + DIR_Y[dir];

if (!isInsideBoard(nx, ny)) continue;
if (board[ny][nx] == -1) cnt++;
}

if (cnt != 0) return;

for (int dir = 0; dir < DIR_LEN; dir++) {
int nx = x + DIR_X[dir];
int ny = y + DIR_Y[dir];

if (!isInsideBoard(nx, ny) || board[ny][nx] == -1) continue;

if (board[ny][nx] != 0) {
unionParent(id, board[ny][nx]);
continue;
}

board[ny][nx] = id;
openTile(nx, ny, id);
}
}

private boolean isInsideBoard(int x, int y) {
return x >= 0 && x < boardSize && y >= 0 && y < boardSize;
}

private void updateAnswer() {
Set<Integer> set = new HashSet<>();
for (int idx = 1; idx < parentArr.length; idx++) {
if (parentArr[idx] == 0) continue;
set.add(parentArr[idx]);
}

answer = set.size();
}

private void print() {
output
.append('#')
.append(testCase)
.append(' ')
.append(answer)
.append('\n');
}

// ----------------------------------------------------------

static String next() throws IOException {
if (input == null || !input.hasMoreTokens())
input = new StringTokenizer(reader.readLine().trim());
return input.nextToken();
}

static int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
112 changes: 112 additions & 0 deletions problems/SWEA/p3289/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* (3289) 서로소 집합
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWBJKA6qr2oDFAWr&categoryId=AWBJKA6qr2oDFAWr&categoryType=CODE&problemTitle=3289&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

import java.io.*;
import java.util.*;

/**
* SW Expert Academy - 서로소 집합
* @author YeJun, Jung
*
* [분석]
* - 런타임에 합집합 연산과 같은 집합에 속해있는지 확인하는 연산을 빠르게 수행해야 하는 문제이다.
*
* [전략]
* - Union-Find 알고리즘 적용
* - Path compression 최적화 사용
*/
public class Solution {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringBuilder output = new StringBuilder();
static StringTokenizer input;

// ----------------------------------------------------------

public static void main(String[] args) throws IOException {
final int testCount = nextInt();

for (int testCase = 1; testCase <= testCount; testCase++) {
new Solution(testCase).run();
}

System.out.print(output.toString());
}

// ----------------------------------------------------------

int testCase;
int answer;
int nodeLen;
int cmdLen;
int[] parentArr;

public Solution(int testCase) { this.testCase = testCase; }
public void run() throws IOException { input(); solve(); print(); }

private void input() throws IOException {
nodeLen = nextInt();
cmdLen = nextInt();
}

private void solve() throws IOException {
output
.append('#')
.append(testCase)
.append(' ');

parentArr = new int[nodeLen + 1];
for (int idx = 1; idx <= nodeLen; idx++) {
parentArr[idx] = idx;
}

int cmd, arg0, arg1;

for (int cnt = 0; cnt < cmdLen; cnt++) {
cmd = nextInt();
arg0 = nextInt();
arg1 = nextInt();

if (cmd == 0) {
// union
unionParent(arg0, arg1);
} else {
// find
output.append(checkParent(arg0, arg1) ? '1' : '0');
}
}
}

private boolean checkParent(int a, int b) {
return findParent(a) == findParent(b);
}

private void unionParent(int a, int b) {
int pa = findParent(a);
int pb = findParent(b);

if (pa != pb) parentArr[pb] = pa;
}

private int findParent(int node) {
if (parentArr[node] == node) return node;
return parentArr[node] = findParent(parentArr[node]);
}

private void print() {
output.append('\n');
}

// ----------------------------------------------------------

static String next() throws IOException {
if (input == null || !input.hasMoreTokens())
input = new StringTokenizer(reader.readLine().trim());
return input.nextToken();
}

static int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
Loading