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
56 changes: 23 additions & 33 deletions problems/SWEA/p1952/Solution.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
/*
* {풀이 하는 중} (1952) [모의 SW 역량테스트] 수영장
* (1952) [모의 SW 역량테스트] 수영장
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PpFQaAQMDFAUq&categoryId=AV5PpFQaAQMDFAUq&categoryType=CODE&problemTitle=1952&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

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

/**
* SW Expert Academy - 1952. [모의 SW 역량테스트] 수영장
* @author YeJun, Jung
*
* [분석]
* - 각 월에 대해서 1일, 1달, 3달 이용권 중 하나를 선택해서 비용의 최소화 해야 한다.
*
* [전략]
* - DFS(재귀함수)를 사용해서 각 월에 대해서 1일, 1달, 3달 이용권을 시도한다.
* - 만약 계산된 가격이 현재까지의 최적 가격보다 높다면 더 이상 탐색하지 않는다. (backtracking)
* - 각 월에 대한 최적 가격을 기록하여 탐색 횟수를 최적화한다.
*/
public class Solution {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
Expand Down Expand Up @@ -38,9 +50,6 @@ public static void main(String[] args) throws IOException {
int[] priceArr;
int[] planArr;

int[] oneDayTicketArr;
boolean[] monthTicketArr;

public Solution(int testCase) {
this.testCase = testCase;
}
Expand Down Expand Up @@ -75,10 +84,6 @@ private void solve() {
}

bestPrice = priceArr[ONE_YEAR_TICKET]; // 1년 이용권

oneDayTicketArr = new int[MONTH_LEN];
monthTicketArr = new boolean[MONTH_LEN];

offset = bestPrice * 2;
cache = new boolean[13 * offset];

Expand All @@ -89,58 +94,43 @@ private void solve() {
boolean[] cache;

private void searchBestPrice(int month, int currentPrice) {
if (month > MONTH_LEN || currentPrice >= bestPrice) return;
// month가 12월을 넘어가지 않도록 한다.
month = Math.min(month, MONTH_LEN);

// 메모이제이션
int cacheKey = month * offset + currentPrice;
// System.out.printf("searchBestPrice(%d, %d)\n", month, currentPrice);
if (cache[cacheKey]) return;
cache[cacheKey] = true;

while ( (month < MONTH_LEN) &&
(monthTicketArr[month] || oneDayTicketArr[month] >= planArr[month])
) {
month++;
}

// 이용하지 않는 달은 넘어간다.
while ( month < MONTH_LEN && planArr[month] == 0) month++;

// 기저조건
if (month >= MONTH_LEN) {
if (currentPrice < bestPrice) bestPrice = currentPrice;
cache[cacheKey] = true;
return;
}

// System.out.printf("[%d] searchBestPrice(%d, %d)\n", testCase, month, currentPrice);

int price;

// 1일 이용권
price = currentPrice + priceArr[ONE_DAY_TICKET];
int price;
price = currentPrice + priceArr[ONE_DAY_TICKET] * planArr[month];
if (price < bestPrice) {
oneDayTicketArr[month]++;
if (oneDayTicketArr[month] >= planArr[month]) {
searchBestPrice(month + 1, price);
} else {
searchBestPrice(month, price);
}
oneDayTicketArr[month]--;
searchBestPrice(month + 1, price);
}

// 1달 이용권
price = currentPrice + priceArr[ONE_MONTH_TICKET];
if (price < bestPrice) {
monthTicketArr[month] = true;
searchBestPrice(month + 1, price);
monthTicketArr[month] = false;
}

// 3달 이용권
price = currentPrice + priceArr[THREE_MONTH_TICKET];
if (price < bestPrice) {
for (int m = month; m < month + 2 && m < MONTH_LEN; m++) monthTicketArr[m] = true;
searchBestPrice(month + 3, price);
for (int m = month; m < month + 2 && m < MONTH_LEN; m++) monthTicketArr[m] = false;
}

// 캐시
cache[cacheKey] = true;
}

Expand Down
9 changes: 0 additions & 9 deletions problems/SWEA/p1952/output.txt

This file was deleted.

130 changes: 130 additions & 0 deletions problems/SWEA/p4012/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* (4012) [모의 SW 역량테스트] 요리사
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeUtVakTMDFAVH&categoryId=AWIeUtVakTMDFAVH&categoryType=CODE&problemTitle=4012&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

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

/**
* SW Expert Academy - 4012. [모의 SW 역량테스트] 요리사
* @author YeJun, Jung
*
* [분석]
* - 주어진 식재료 중에서 N/2를 선택해서 조합한다.
* - 식재료를 조합해서 시너지를 합친다.
* - 두 요리의 시너지 차이의 최솟값을 출력한다.
*
* [전략]
* - 조합을 위해 prevPermutation 메서드를 사용한다.
* - getFoodScore 메서드에서 2중 반복문을 통해 사용한 식재료의 시너지 합을 계산한다.
*/
public class Solution {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
static StringTokenizer input;

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

public static void main(String[] args) throws IOException {
final int testCount = Integer.parseInt(reader.readLine().trim());

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

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

int testCase;
int answer;
int matSize;
int[][] mat;
int[] select;

public Solution(int testCase) {
this.testCase = testCase;
}

public void run() throws IOException {
input();
solve();
print();
}

private void input() throws IOException {
matSize = Integer.parseInt(reader.readLine().trim());
mat = new int[matSize][matSize];

for (int y = 0; y < matSize; y++) {
getLine();

for (int x = 0; x < matSize; x++) {
mat[y][x] = Integer.parseInt(input.nextToken());
}
}
}

private void solve() {
answer = Integer.MAX_VALUE;
select = new int[matSize];

Arrays.fill(select, 0, matSize / 2, 1);

do {
answer = Math.min(answer, search());
} while (prevPermutation(select));
}

private int search() {
int foodA = getFoodScore(0);
int foodB = getFoodScore(1);

return Math.abs(foodA - foodB);
}

private int getFoodScore(int food) {
int result = 0;

for (int A = 0; A < matSize; A++) {
if (select[A] != food) continue;
for (int B = 0; B < matSize; B++) {
if (select[B] != food) continue;

result += mat[A][B];
}
}

return result;
}

private void print() throws IOException {
writer.write("#" + testCase);
writer.write(" " + answer);
writer.write("\n");
writer.flush();
}

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

private static void getLine() throws IOException {
input = new StringTokenizer(reader.readLine().trim());
}

private static boolean prevPermutation(int[] x) {
int n = x.length - 1, a = n, b = n;
while (a > 0 && x[a - 1] <= x[a]) a--;
if (a == 0) return false;
while (x[a - 1] <= x[b]) b--;
swap(x, a - 1, b); reverse(x, a, n);
return true;
}

private static void swap(int[] x, int a, int b) {
int t = x[a]; x[a] = x[b]; x[b] = t;
}

private static void reverse(int[] x, int a, int b) {
while (a < b) swap(x, a++, b--);
}
}
95 changes: 95 additions & 0 deletions problems/SWEA/p6782/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* (6782) 현주가 좋아하는 제곱근 놀이
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWgqsAlKr9sDFAW0&categoryId=AWgqsAlKr9sDFAW0&categoryType=CODE&problemTitle=6782&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

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

/**
* SW Expert Academy - 6782. 현주가 좋아하는 제곱근 놀이
* @author YeJun, Jung
*
* [분석]
* - 주어진 N을 N+1 하면서 sqrt(N) 결과 (정수)가 되도록 만들어야 한다.
* - sqrt(N)은 비용이 낮지만, N+1은 너무 많이 반복해야 한다.
* - 주어지는 숫자가 크기 때문에(10¹²) Long 타입을 사용한다.
*
* [전략]
* - 사전에 2...1,000,000 까지 제곱해서 저장해두고 활용한다.(백만번 반복)
* - sqrt(N) 결과 정수가 아니어서 N+1 해야할 때 사전에 계산해둔 제곱근 결과를 활용한다.
*/
public class Solution {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

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

public static void main(String[] args) throws IOException {
final int testCount = Integer.parseInt(reader.readLine().trim());

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

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

static final int MAX_POW = 1000001;
static long[] powArr = new long[MAX_POW];

static {
// 사전에 2...1,000,000 까지 제곱해서 저장해두고 활용한다.(백만번 반복)
for (long num = 2; num < MAX_POW; num++) {
powArr[(int)(num)] = num * num;
}
}

int testCase;
long startNum;
int answer;

public Solution(int testCase) {
this.testCase = testCase;
}

public void run() throws IOException {
input();
solve();
print();
}

private void input() throws IOException {
startNum = Long.parseLong(reader.readLine().trim());
}

private void solve() {
answer = countUntilTwo(startNum);
}

private int countUntilTwo(long num) {
// 기저 조건
if (num == 2) return 0;

// 일단 sqrt(num) 한다.
int sqrt = (int)Math.sqrt(num);

// sqrt(num) 결과가 정수라면, 바로 sqrt(num) 결과를 적용한다.
if (powArr[sqrt] == num) {
return 1 + countUntilTwo(sqrt);
}

// sqrt(num) 결과가 정수가 아니라면, 정수가 되도록 num을 조정한다.
sqrt++;
return (int)(powArr[sqrt] - num) + countUntilTwo(powArr[sqrt]);
}

private void print() throws IOException {
writer.write("#" + testCase);
writer.write(" " + answer);
writer.write("\n");
writer.flush();
}

// ----------------------------------------------------------
}
Loading