1. 문제 링크
https://www.acmicpc.net/problem/1340
2. 문제

요약
- 입력되는 날짜가 해당 연도 새해부터 얼마나 지났는지를 퍼센트로 출력합니다.
- 입력: '달 일, 연도 시:분' 형식으로 입력이 주어집니다.
- 출력: 입력된 시간이 새해부터 얼마나 지났는지를 퍼센트로 출력합니다.
3. 소스코드
초기 버전
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main {
public double NewYearPer(ArrayList<String> input_arr) {
double result = 0;
HashMap<String, Integer> month = new HashMap<String, Integer>() {{
put("January", 1);
put("February", 2);
put("March", 3);
put("April", 4);
put("May", 5);
put("June", 6);
put("July", 7);
put("August", 8);
put("September", 9);
put("October", 10);
put("November", 11);
put("December", 12);
}};
int[] month_day = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if((Integer.parseInt(input_arr.get(2)) % 400 == 0) || ((Integer.parseInt(input_arr.get(2)) % 4 == 0) && (Integer.parseInt(input_arr.get(2)) % 100 != 0))) {
double total_min = 366 * 24 * 60;
double current_min = 0;
int total_date = 0;
for(int i = 0; i < month.get(input_arr.get(0)) - 1; i++) {
if(i == 1) {
total_date += month_day[i] + 1;
continue;
}
total_date += month_day[i];
}
total_date += Integer.parseInt(input_arr.get(1)) - 1;
current_min += (total_date * 24 * 60) + (Integer.parseInt(input_arr.get(3)) * 60) + Integer.parseInt(input_arr.get(4));
result = (current_min * 100) / total_min;
} else {
double total_min = 365 * 24 * 60;
double current_min = 0;
int total_date = 0;
for(int i = 0; i < month.get(input_arr.get(0)) - 1; i++) {
total_date += month_day[i];
}
total_date += Integer.parseInt(input_arr.get(1)) - 1;
current_min += (total_date * 24 * 60) + (Integer.parseInt(input_arr.get(3)) * 60) + Integer.parseInt(input_arr.get(4));
result = (current_min * 100) / total_min;
}
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
StringTokenizer st = new StringTokenizer(input, " ,:");
ArrayList<String> input_arr = new ArrayList<String>();
while(st.hasMoreTokens()) {
input_arr.add(st.nextToken());
}
Main m = new Main();
double result = m.NewYearPer(input_arr);
System.out.println(result);
}
}
수정된 버전
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main {
public int getTotalDate(ArrayList<String> input_arr, HashMap<String, Integer> month, int[] month_day) {
int total_date = 0;
if((Integer.parseInt(input_arr.get(2)) % 400 == 0) || ((Integer.parseInt(input_arr.get(2)) % 4 == 0) && (Integer.parseInt(input_arr.get(2)) % 100 != 0))) {
for(int i = 0; i < month.get(input_arr.get(0)) - 1; i++) {
if(i == 1) {
total_date += month_day[i] + 1;
continue;
}
total_date += month_day[i];
}
} else {
for(int i = 0; i < month.get(input_arr.get(0)) - 1; i++) {
total_date += month_day[i];
}
}
return total_date;
}
public double NewYearPer(ArrayList<String> input_arr) {
double result = 0;
HashMap<String, Integer> month = new HashMap<String, Integer>() {{
put("January", 1);
put("February", 2);
put("March", 3);
put("April", 4);
put("May", 5);
put("June", 6);
put("July", 7);
put("August", 8);
put("September", 9);
put("October", 10);
put("November", 11);
put("December", 12);
}};
int[] month_day = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
double total_min = 0;
double current_min = 0;
if((Integer.parseInt(input_arr.get(2)) % 400 == 0) || ((Integer.parseInt(input_arr.get(2)) % 4 == 0) && (Integer.parseInt(input_arr.get(2)) % 100 != 0))) {
total_min = 366 * 24 * 60;
} else {
total_min = 365 * 24 * 60;
}
int total_date = getTotalDate(input_arr, month, month_day);
total_date += Integer.parseInt(input_arr.get(1)) - 1;
current_min += (total_date * 24 * 60) + (Integer.parseInt(input_arr.get(3)) * 60) + Integer.parseInt(input_arr.get(4));
result = (current_min * 100) / total_min;
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
StringTokenizer st = new StringTokenizer(input, " ,:");
ArrayList<String> input_arr = new ArrayList<String>();
while(st.hasMoreTokens()) {
input_arr.add(st.nextToken());
}
Main m = new Main();
double result = m.NewYearPer(input_arr);
System.out.println(result);
}
}
4. 접근
- 현재 시간이 새해부터 얼마나 지났는지는 주어지는 시간이 분 단위까지 나타나있으므로 해당 연도의 전체 분에 해당하는 숫자로 현재 시간까지의 분에 해당하는 숫자를 나누면 퍼센트가 나옵니다.
- 윤년이 존재하기 때문에 윤년을 검사해줘야 하고, 윤년을 검사하는 방법은 해당 연도가 400으로 나누어 떨어지거나 4로 나누어 떨어지면서 100으로 나누어 떨어지지 않는 연도가 윤년입니다.
- 해당 연도의 전체 분에 해당하는 숫자는 해당 연도의 일수 * 24 * 60을 하면 구할 수 있습니다.
- 현재 시간까지의 분에 해당하는 숫자는 우선 새해부터 며칠이 지났는지 계산을 한 후, 이를 분으로 환산하고 시간을 분으로 환산한 후, 환산한 숫자들과 현재 분을 더하면 해당 숫자를 구할 수 있습니다.
- 퍼센트를 구하기로 하였으므로, 현재 시간까지의 분에 해당하는 숫자에 100을 곱한 후, 해당 연도의 전체 분에 해당하는 숫자로 나누면 퍼센트를 구할 수 있습니다.
- 초기 버전에서는 이러한 로직을 한 함수에 모두 넣어놨고, 윤년과 평년에 겹치는 로직들을 중복하여 적어주었습니다.
- 수정한 버전에서는 겹치는 로직들을 하나로 합쳐주었고, 현재 시간을 구하는 로직을 하나의 함수로 작성하여 유지보수성을 높였습니다.