Q. https://www.acmicpc.net/problem/20546
20546번: 🐜 기적의 매매법 🐜
1월 14일 기준 준현이의 자산이 더 크다면 "BNP"를, 성민이의 자산이 더 크다면 "TIMING"을 출력한다. 둘의 자산이 같다면 "SAMESAME"을 출력한다. 모든 결과 따옴표를 제외하고 출력한다.
www.acmicpc.net
# 아이디어
준현(BNP) vs 성민(TIMING)
BNP: 살 수 있을 때 전부 다 사기
=> 14일 마지막 날에만 주식을 팜.
TIMING: 3일 연속 하락하면 풀매수, 3일 연속 상승하면 풀매도
=> 전 날 주가와 비교해서 3일 연속 상승하면 1, 3일 연속 하락하면 0. check() 함수.
# 오답
Sol 1.
- 오늘의 주가에 해당하는 만큼 돈이 없으면 밑에 볼 필요 없이 바로 다음날로 넘김.
- Scanner에서 BufferedReader 사용함.
package baekjoon;
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Person {
private int money;
private int[] chart;
private int count;
public Person(int money, int[] chart) {
this.money = money;
this.chart = chart;
this.count = 0;
}
public int check(int[] check) {
int flag = 0;
for (int i = 0; i < check.length; i++) {
if (check[i] == 1)
flag++;
else if (check[i] == 0)
flag--;
}
if (flag == 3)
return 1;
else if (flag == -3)
return 0;
return -1;
}
public void BNP() {
int day = 1;
int mul = 1;
while (true) {
if (day == 15) {
break;
}
if (money < chart[day - 1]) {
day++;
continue;
}
while (!(money < chart[day - 1] * mul)) {
mul++;
}
mul--;
money = money - chart[day - 1] * mul;
count += mul;
mul = 1;
day++;
}
}
public void TIMING() {
int day = 1;
int mul = 1;
int[] check = new int[3];
while (true) {
if (day == 12) {
break;
}
if (day < 4) {
day++;
continue;
}
if (money < chart[day - 1]) {
day++;
continue;
}
for (int i = 0; i < check.length; i++) {
if (chart[(day - 1) + i] < chart[(day - 1) + i + 1]) {
check[i] = 1;
} else if (chart[(day - 1) + i] > chart[(day - 1) + i + 1]) {
check[i] = 0;
}
}
if (check(check) == 1) {
while (!(money < chart[day - 1] * mul)) {
mul++;
}
mul--;
money = money - chart[day - 1] * mul;
count += mul;
mul = 1;
day++;
} else if (check(check) == 0) {
money += chart[day - 1] * count;
count = 0;
day++;
} else {
day++;
}
}
}
public int getMoney() {
return money + chart[13] * count;
}
}
public class S20546 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int money = Integer.parseInt(br.readLine());
String[] input = br.readLine().split(" ");
int[] chart = new int[14];
for (int i = 0; i < chart.length; i++) {
chart[i] = Integer.parseInt(input[i]);
}
Person junhyeon = new Person(money, chart);
junhyeon.BNP();
Person sungmin = new Person(money, chart);
sungmin.TIMING();
if (junhyeon.getMoney() > sungmin.getMoney())
System.out.println("BNP");
else if (junhyeon.getMoney() < sungmin.getMoney())
System.out.println("TIMING");
else
System.out.println("SAMESAME");
}
}
=> 런타임에러 발생... 코드 갈고 다시 시작하자! 💢💢💢
Sol2.
- 예제는 꼭꼭 씹어먹기.. 위에꺼 하나만 보지 말자..... 제발!!!
- 바보 멍청이같은 짓을 했다...
주식을 몇 개 살지 계산하기 위해 junCount와 seoungCount가 for문 안에서 초기화가 되고 있었다...!!!
코드를 새로 짜다보니 이전에 뭣도 모르고 우연찮게 올바르게 작성한 부분을 찾을 수 있었다... ㅠㅠ
변수가 하는 일?에 대해서 명확히 해두자!!! mul과 사람의 Count를 헷갈리지 않도록...
- 주식을 사야하는 TIMING이더라도 해당 날짜의 주가만큼 돈이 없으면 바로 다음날로 넘어가도록 했다.
- check 함수를 static 함수로 생성해 오늘과 이전 3일의 주가를 비교할 수 있도록 좀 더 명확히 상황을 제어했다.
package baekjoon;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class S20546 {
public static int check(int[] chart, int day) {
int[] check = new int[3];
Arrays.fill(check, -1);
int cnt = 0;
for (int i = day - 3; i < day; i++) {
if (chart[i] < chart[i + 1]) {
check[cnt] = 1;
cnt++;
} else if (chart[i] > chart[i + 1]) {
check[cnt] = 0;
cnt++;
} else {
cnt++;
}
}
int flag = 0;
for (int i = 0; i < check.length; i++) {
if (check[i] == 1) {
flag++;
} else if (check[i] == 0) {
flag--;
} else
return -1;
}
if (flag == 3) // 전량 매도
return 1;
else if (flag == -3) // 전량 매수
return 0;
return -1;
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int money = Integer.parseInt(br.readLine());
String[] input = br.readLine().split(" ");
int[] chart = new int[14];
for (int i = 0; i < chart.length; i++) {
chart[i] = Integer.parseInt(input[i]);
}
int junMoney = money;
int junCount = 0;
for (int day = 0; day < chart.length; day++) {
if (chart[day] > junMoney) {
continue;
}
int mul = 1;
while (junMoney >= chart[day] * mul) {
mul++;
}
junCount += --mul;
junMoney -= chart[day] * junCount;
}
junMoney += chart[13] * junCount;
int seoungMoney = money;
int seoungCount = 0;
// 4일치 데이터가 있어야 시작함.
for (int day = 3; day < chart.length; day++) {
if (chart[day] > seoungMoney) {
continue;
}
if (check(chart, day) == 0) {
int mul = 1;
while (seoungMoney >= chart[day] * mul) {
mul++;
}
seoungCount += --mul;
seoungMoney -= chart[day] * seoungCount;
} else if (check(chart, day) == 1) {
seoungMoney += chart[day] * seoungCount;
seoungCount = 0;
} else {
continue;
}
}
seoungMoney += chart[13] * seoungCount;
if (junMoney > seoungMoney)
System.out.println("BNP");
else if (junMoney < seoungMoney)
System.out.println("TIMING");
else
System.out.println("SAMESAME");
}
}
=> 띠용 런타임에러??? BufferedReader를 쓰니까 런타임 에러가 뜨네...
Scanner로 바꿔보자!
Sol3.
Scanner로 바꾸니까 성공..
코테에서 입력과 출력이 너무 어렵다.. 🤔
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static int check(int[] chart, int day) {
int[] check = new int[3];
Arrays.fill(check, -1);
int cnt = 0;
for (int i = day - 3; i < day; i++) {
if (chart[i] < chart[i + 1]) {
check[cnt] = 1;
cnt++;
} else if (chart[i] > chart[i + 1]) {
check[cnt] = 0;
cnt++;
} else {
cnt++;
}
}
int flag = 0;
for (int i = 0; i < check.length; i++) {
if (check[i] == 1) {
flag++;
} else if (check[i] == 0) {
flag--;
} else
return -1;
}
if (flag == 3) // 전량 매도
return 1;
else if (flag == -3) // 전량 매수
return 0;
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int money = sc.nextInt();
int[] chart = new int[14];
for (int i = 0; i < chart.length; i++) {
chart[i] = sc.nextInt();
}
int junMoney = money;
int junCount = 0;
for (int day = 0; day < chart.length; day++) {
if (chart[day] > junMoney) {
continue;
}
int mul = 1;
while (junMoney >= chart[day] * mul) {
mul++;
}
junCount += --mul;
junMoney -= chart[day] * junCount;
}
junMoney += chart[13] * junCount;
int seoungMoney = money;
int seoungCount = 0;
// 4일치 데이터가 있어야 시작함.
for (int day = 3; day < chart.length; day++) {
if (chart[day] > seoungMoney) {
continue;
}
if (check(chart, day) == 0) {
int mul = 1;
while (seoungMoney >= chart[day] * mul) {
mul++;
}
seoungCount += --mul;
seoungMoney -= chart[day] * seoungCount;
} else if (check(chart, day) == 1) {
seoungMoney += chart[day] * seoungCount;
seoungCount = 0;
} else {
continue;
}
}
seoungMoney += chart[13] * seoungCount;
if (junMoney > seoungMoney)
System.out.println("BNP");
else if (junMoney < seoungMoney)
System.out.println("TIMING");
else
System.out.println("SAMESAME");
sc.close();
}
}
# 코드 리뷰
check 함수 간결하게(불필요한 내용들 삭제)
public static int check(int[] chart, int day) {
int flag = 0;
for (int i = day-3; i < day; i++) {
if (chart[i] < chart[i + 1]) {
flag++;
} else if (chart[i] > chart[i + 1]) {
flag--;
} else
return -1;
}
if (flag == 3) // 전량 매도
return 1;
else if (flag == -3) // 전량 매수
return 0;
return -1;
}
💯💯💯
구현 문제에서는 코드 가독성, 최적화 중요!!!
※ BufferedReader
'코테문제' 카테고리의 다른 글
[백준] B11170 (0) | 2023.10.12 |
---|---|
[백준] B2460 (0) | 2023.09.29 |
[백준] S17276 미완성 (0) | 2023.09.27 |
[백준] S1913 (0) | 2023.09.24 |
[백준] B14467 (0) | 2023.09.15 |