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
239 changes: 239 additions & 0 deletions problems/SWEA/p5644/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/*
* (5644) [모의 SW 역량테스트] 무선 충전
* https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRDL1aeugDFAUo&categoryId=AWXRDL1aeugDFAUo&categoryType=CODE&problemTitle=5644&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1
*/

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

/**
* SW Expert Academy - 5644. [모의 SW 역량테스트] 무선 충전
* @author YeJun, Jung
*
* [전략]
* - 문제에서 제시된 조건에 따라 시뮬레이션을 충실히 수행한다.
* - OOP를 적절히 사용하여 개발과정에서 실수를 줄인다.
*
* [주요 코드]
* - input()
* - BC를 입력받아 towerArr에 저장한다.
* - 입력이 끝난후 towerArr 마지막에 더미 BC를 하나 추가한다.
* - 시뮬레이션 과정에서 사람이 BC 범위 밖에 있을때 더미 BC를 가르킨다.
* - solve()
* - 두 사람의 초기위치를 설정한 후, 시뮬레이션을 시작한다.
* - runSimuration()
* - 먼저 BC에서 충전한 에너지를 반영하고, 이동한다.
* - 시뮬레이션 종료 후 마지막 위치에서의 에너지도 반영한다.
* - updateEnergy()
* - 두 사람이 밟고 있는 BC는 towerCheck 배열에 true로 표시된다.
* - 밟고 있는 BC가 없으면 더미BC가 true 된다.
* - 2중 반복문을 통해 두 사람이 밟고 있는 BC 중에서 하나씩 선택한다.
* - 두 사람이 동일한 BC를 밟고 있다면 받는 에너지가 절반이 된다.
* - 가능한 최대 에너지를 받을 수 있는 BC가 선택된다.
* - moving(int t)
* - t 시간에 움직인 방향으로 사람들을 이동시킨다.
* - isInsideTower(int personIdx, int towerIdx)
* - 문제에서 제시된 거리 공식에 따라 파라미터로 입력된 사람이
* BC 범위에 있는지 검사한다.
*/
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();
}
}

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

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

final static int[] BC_AREA_X = { 0, 1, 1, 1, 0, -1, -1, -1 };
final static int[] BC_AREA_Y = { -1, -1, 0, 1, 1, 1, 0, -1 };
final static int BC_AREA_LEN = 8;

final static int BOARD_SIZE = 10;
final static int MAX_TOWER_COUNT = 8;
final static int PERSON_COUNT = 2;

int testCase;
int energy; // answer
int totalMovingTime;
int towerCount;
char[][] move;
Tower[] towerArr;
Pos[] people;

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

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

public void input() throws IOException {
getLine();
totalMovingTime = Integer.parseInt(input.nextToken());
towerCount = Integer.parseInt(input.nextToken());

move = new char[2][totalMovingTime];
for (int person = 0; person < PERSON_COUNT; person++) {
getLine();

for (int t = 0; t < totalMovingTime; t++) {
move[person][t] = input.nextToken().charAt(0);
}
}

towerArr = new Tower[towerCount + 1];
for (int index = 0; index < towerCount; index++) {
towerArr[index] = Tower.fromReader();
}
towerArr[towerCount] = new Tower(-1, -1, 0, 0);
}

public void solve() {
energy = 0;

initPeople();
runSimutation();
}

private void initPeople() {
people = new Pos[2];

people[0] = new Pos(0, 0);
people[1] = new Pos(BOARD_SIZE - 1, BOARD_SIZE - 1);
}

private void runSimutation() {
for (int t = 0; t < totalMovingTime; t++) {
updateEnergy();
moving(t);
}
updateEnergy();
}

private void updateEnergy() {
int bestEnergy = 0;
boolean[][] towerCheck = new boolean[PERSON_COUNT][towerCount + 1];

for (int person = 0; person < PERSON_COUNT; person++) {
int x = people[person].x;
int y = people[person].y;
boolean hasTower = false;

for (int tower = 0; tower < towerCount; tower++) {
if (!isInsideTower(person, tower)) continue;

towerCheck[person][tower] = true;
hasTower = true;
}

if (!hasTower) {
towerCheck[person][towerCount] = true;
}
}

for (int selectA = 0; selectA < towerCount + 1; selectA++) {
if (!towerCheck[0][selectA]) continue;
Tower towerA = towerArr[selectA];

for (int selectB = 0; selectB < towerCount + 1; selectB++) {
if (!towerCheck[1][selectB]) continue;
Tower towerB = towerArr[selectB];

int currentEnergy = towerA.power + towerB.power;
if (selectA == selectB) currentEnergy /= 2;

if (currentEnergy > bestEnergy) {
bestEnergy = currentEnergy;
}
}
}

energy += bestEnergy;
}

private void moving(int t) {
for (int person = 0; person < PERSON_COUNT; person++) {
int dir = move[person][t] - '0';

people[person].x += DIR_X[dir];
people[person].y += DIR_Y[dir];
}
}

private boolean isInsideTower(int personIdx, int towerIdx) {
Pos person = people[personIdx];
Tower tower = towerArr[towerIdx];

int distance = Math.abs(person.x - tower.x) + Math.abs(person.y - tower.y);

return distance <= tower.size;
}

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

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

private static class Tower {
int x;
int y;
int size;
int power;

public Tower(int x, int y, int size, int power) {
this.x = x;
this.y = y;
this.size = size;
this.power = power;
}

public static Tower fromReader() throws IOException {
getLine();

int x = Integer.parseInt(input.nextToken()) - 1;
int y = Integer.parseInt(input.nextToken()) - 1;
int size = Integer.parseInt(input.nextToken());
int power = Integer.parseInt(input.nextToken());

return new Tower(x, y, size, power);
}
}

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

private static class Pos {
int x;
int y;

public Pos(int x, int y) {
this.x = x;
this.y = y;
}
}

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

private static void getLine() throws IOException {
input = new StringTokenizer(reader.readLine().trim());
}
}
123 changes: 123 additions & 0 deletions problems/SWEA/p7206/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* (7206) 숫자 게임
* https://swexpertacademy.com/main/code/userProblem/userProblemDetail.do?contestProbId=AWlGyBQqaEgDFASG&categoryId=AWlGyBQqaEgDFASG&categoryType=CODE
*/

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

/**
* SW Expert Academy - 7206. 숫자 게임
* @author YeJun, Jung
*
* [주요 변수]
* - 주어진 시작 숫자 = startNum
* - 숫자의 각 자리의 중간(자르는 부분)의 길이 = numLen
*
* [탐색]
* - 숫자의 어디를 자를 건지, 부분집합으로 결정
* - 숫자의 최대길이가 5(99999) 이므로 BitMask(int, 32bit)로 충분히 처리 가능
* - BitMask를 사용해서 부분집합 생성
* - 숫자를 잘라서 곱한 후, 다음 탐색으로 이동
* - 재귀함수를 사용
* - 가장 turnCount가 값을 선택한다.
*
* [최적화]
* - 메모이제이션 방법을 사용
* - solve() 함수의 파라미터와 리턴값을 기록해 두었다가, 활용
*/
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();
}
}

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

static int[] cache = new int[100000];

int testCase;
int startNum;
int answer;

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

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

public void input() throws IOException {
startNum = Integer.parseInt(reader.readLine().trim());
}

public void solve() {
answer = search(startNum, 0);
}

private int search(int num, int turnCount) {
if (num < 10) return 0;
if (cache[num] != 0) return cache[num];

final int numLen = getNumLen(num) - 1;
final int last = 1 << numLen;

int bestTurnCount = 0;

for (int mask = 1; mask != last; mask++) {
int target = num;
int nextNum = 1;

for (int index = 0; index < numLen; index++) {
if ((mask & (1 << index)) == 0) continue;

int[] split = splitNum(target, numLen - index);
nextNum *= split[0];
target = split[1];
}
if (target > 0) nextNum *= target;

bestTurnCount = Math.max(bestTurnCount, 1 + searchRecrusive(nextNum, turnCount + 1));
}

cache[num] = bestTurnCount;
return bestTurnCount;
}

private int getNumLen(int num) {
int result = 0;
for (; num > 0; result++) num /= 10;
return result;
}

private int[] splitNum(int num, int index) {
int cutter = 10;
for (int cnt = 1; cnt < index; cnt++) cutter *= 10;
return new int[] { num / cutter, num % cutter };
}

public 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());
}
}