https://www.acmicpc.net/step/52
오늘은 심화1을 단계별 문제로 풀었다.
심화1 총 8문제를 풀었다.
이전에 풀었던 문제들보다 생각 할 것들이 있었다.
풀었던 문제중에서 인상깊었던 문제 몇 개를 적어본다.
백준 1157 - 단어 공부
https://www.acmicpc.net/problem/1157
문제분석
요약하자면,
1. 알파벳 대소문자로 된 단어가 주어진다.
2. 가장 많이 사용된 알파벳을 출력하라
3. 대소문자 구분없이 사용횟수를 세며, 여러 개 존재하는 경우 ?를 출력한다.
3번 조건을 고려해, 대소문자 구분없이 사용횟수를 세기위해서, 입력받은 단어를 대문자든 소문자 하나로 통일해서 바꿔주도록 한다.
등장횟수를 카운트해서 Map에 저장을 한다. 알파벳: 횟수 의 키:값을 가지도록.
이후 Map을 루프하면서 maxCount를 찾아서 가장 많이 사용된 알파벳을 출력한다.
여기서 만약 maxCount와 같은, 즉 같은 횟수의 가장 많이 사용된 알파벳이 등장한다면, 출력값을 "?"로 출력하도록 한다.
정답
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String word = sc.nextLine();
word = word.toUpperCase(); // 입력된 단어를 모두 대문자로 변경
Map<Character, Integer> charCount = new HashMap<>();
// 각 알파벳의 등장 횟수를 카운트
for (char c : word.toCharArray()) {
if (Character.isLetter(c)) {
charCount.put(c, charCount.getOrDefault(c, 0) + 1);
}
}
int maxCount = 0;
char mostFrequentChar = '?';
// 가장 많이 등장한 알파벳 찾기
for (char c : charCount.keySet()) {
if (charCount.get(c) > maxCount) {
maxCount = charCount.get(c);
mostFrequentChar = c;
} else if (charCount.get(c) == maxCount) {
mostFrequentChar = '?'; // 가장 많이 등장한 알파벳이 여러 개인 경우
}
}
System.out.println(mostFrequentChar);
sc.close();
}
}
1. toUpperCase로 String을 대문자로 바꿔서 다시 저장해준다.
2. 알파벳의 등장횟수를 Map에 넣어서 카운트해준다. getOrDefault로 c의 키값에 해당하는 값이 있으면 가져오고, 없다면 0을 반환한다. 그리고 1을 더해준다.
3. key값을 순환하면서 최빈 알파벳을 찾으면, mostFrequenChar를 c로 만들어주면서 maxCount인 알파벳을 넣어준다. 만약 가져온 Value가 maxCount와 같다면, 2개 이상이라는 뜻으로 mostFrequenChar를 ?로 만들어주었다.
백준 2941 - 크로아티아 알파벳
https://www.acmicpc.net/problem/2941
문제분석
문제를 요약해보자.
처음 문제를 봤을 때는, 이게 뭐야?? 라는 생각이 들었는데, 생각보다 간단했다.
변경되어 있는 단어가 주어지면, 해당 크로아티아 알파벳이 몇개로 이루어져있는지 알아보는 문제이다.
만약 단어가 "ddz=z=" 라면,
dz= , z= 2개가 포함되어 3개의 크로아티아 알파벳으로 이루어져 있다.
그러면 if문이다 case로 해당 부분들을 나누어서 단어를 순환하면 된다.
정답
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int count = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(ch == 'c') { // 만약 ch 가 c 라면?
if(i < str.length() - 1) {
if(str.charAt(i + 1) == '=') { //만약 ch 다음 문자가 '=' 이라면?
// i+1 까지가 하나의 문자이므로 다음 문자를 건너 뛰기 위해 1 증가
i++;
}
else if(str.charAt(i + 1) == '-') {
i++;
}
}
}
else if(ch == 'd') {
if(i < str.length() - 1) {
if(str.charAt(i + 1) == 'z') {
if(i < str.length() - 2) {
if(str.charAt(i + 2) == '=') { // dz= 일 경우
i += 2;
}
}
}
else if(str.charAt(i + 1) == '-') { // d- 일 경우
i++;
}
}
}
else if(ch == 'l') {
if(i < str.length() - 1) {
if(str.charAt(i + 1) == 'j') { // lj 일 경우
i++;
}
}
}
else if(ch == 'n') {
if(i < str.length() - 1) {
if(str.charAt(i + 1) == 'j') { // nj 일 경우
i++;
}
}
}
else if(ch == 's') {
if(i < str.length() - 1) {
if(str.charAt(i + 1) == '=') { // s= 일 경우
i++;
}
}
}
else if(ch == 'z') {
if(i < str.length() - 1) {
if(str.charAt(i + 1) == '=') { // z= 일 경우
i++;
}
}
}
count++;
}
System.out.println(count);
}
}
String을 받아온 후 charAt으로 한글자한글자씩 순환하면서 비교한다.
만약 c가 들어온다면,
stringlength -1의 조건을 붙인다. 다음에 이어질 단어를 비교해야 하기 때문이다.
이후 만약 i+1의 문자가 "="라면, 즉 "c=" 라면, i를 증가시키고, count를 하나 증가시킨다.
다른 case도 똑같이 else if로 처리해준 후 count를 출력한다.
백준 1316 - 그룹단어 검사
https://www.acmicpc.net/problem/1316
문제분석
문제를 요약하자면,
aaabbbccc 와 같이 연속된 알파벳이 나타나는 단어를 그룹단어라고 칭한다.
만약 aabbccb는 b가 연속되지 않고 한번 더 나왔으므르로 그룹단어라고 칭하지 않는다.
그룹단어를 구별하는 함수를 구현하고, 해당 함수를 N번 반복해서 루프를 돌리면 될 것 같다.
정답
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // 단어의 개수 입력
int groupWordCount = 0; // 그룹 단어의 개수를 세기 위한 변수
// 단어의 개수(N)만큼 반복하여 그룹 단어인지 확인
for (int i = 0; i < N; i++) {
String word = sc.next();
if (isGroupWord(word)) {
groupWordCount++;
}
}
System.out.println(groupWordCount);
sc.close();
}
// 그룹 단어인지 확인하는 메소드
public static boolean isGroupWord(String word) {
boolean[] visited = new boolean[26]; // 알파벳 개수(소문자 기준)만큼의 배열
for (int i = 0; i < word.length(); i++) {
char currentChar = word.charAt(i);
int index = currentChar - 'a'; // 현재 문자의 인덱스 계산
// 현재 문자가 이전에 나왔고, 바로 앞 문자와 다르다면 그룹 단어가 아님
if (visited[index] && word.charAt(i - 1) != currentChar) {
return false;
}
visited[index] = true; // 현재 문자를 방문했음을 표시
}
return true; // 그룹 단어인 경우
}
}
일단 Scanner로 N을 받아서 그룹 단어의 갯수를 받을 횟수를 받는다.
for루프로 N번 반복하는데, 여기서 필요한게 isGroupWord라는 함수이다.
isGroupWord 함수는 boolean형으로 출력해서 해당 단어가 그룹단어인지 아닌지 판단한다.
알파벳의 갯수만큼의 boolean배열을 준비한다.
여기서 String의 길이만큼 루프를 돌리면서 해당 알파벳의 인덱스를 구해서 해당 인덱스의 알파벳위치를 true로 만든다.
만약 해당 위치의 boolean값이 true이면서(이전에 등장했던 알파벳) 이전자리의 알파벳이 현재 알파벳과 다르면 해당 단어는 그룹 단어가 아니다. (예를들어 aaba 와 같이 이미 등장했으면서 현재 a와 이전 b는 다른 알파벳이므로)
해당 함수가 true이면 groupWordCount를 증가시켜 최종적으로 출력한다.
백준 25206 - 학점 계산기
https://www.acmicpc.net/problem/25206
문제분석
단계별 풀이 심화1의 마지막인 "너의 평점은"문제이다.
입력이 전공 학점 평점 세가지가 20번이나 들어오고, 이걸 정리해서 전공평점으로 출력하는 문제이다.
많은양의 데이터를 받으면서, 한줄에 3가지 정보를 잘라서 받아야하므로,
BufferedReader를 사용하고, StringTokenizer를 통해서 데이터를 구분해서 받는다.
이후 각 강의의 성적을 판단할 배열을 만들어서 score에 적용해줄 것이다.
1. 한줄한줄의 데이터를 저장할 배열 str을 20크기로 만든다.
2. 성적을 판단할 A+와 같이 문자로된 배열과 그에 맞는 점수가 있는 배열을 만든다.
3. 20번의 루프를 돌면서 bufferedReader로 한줄의 데이터를 받아서 str에 저장한다.
4. StringTokenizer로 str을 빈칸으로 구분해서 쪼개서 subject, score, grade로 저장한다.
5. 10번의 루프(성적배열크키)통해서 총점수를 계산한다.
6. 전공평점을 구해서 소수점 6자리까리 출력하도록 한다.
정답
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
String str[] = new String[20];
double totalSum = 0;
double scoreSum = 0;
String gradeList[] = {"A+", "A0", "B+", "B0", "C+", "C0", "D+", "D0", "F", "P"};
double gradeScore[] = {4.5, 4.0, 3.5, 3.0, 2.5, 2.0, 1.5, 1.0, 0.0, 0.0};
for (int i = 0; i < 20; i++) {
str[i] = bfr.readLine();
StringTokenizer st = new StringTokenizer(str[i], " ");
String subject = st.nextToken();
double score = Double.parseDouble(st.nextToken());
String grade = st.nextToken();
for (int j = 0; j < 10; j++) {
if (grade.equals(gradeList[j])) {
totalSum += score * gradeScore[j];
if (j != 9) {
scoreSum += score;
}
}
}
}
double average = totalSum / scoreSum;
System.out.printf("%.6f\n", average);
bfr.close();
}
}
이때까지의 과정이 어느정도 종합되어 있는 듯한 문제라는 느낌이 들었다.
처음 보았을 때는 엄청 복잡해 보이는 문제였지만 잘 활용하면 그렇게 어려운 문제는 아니었다.
'Code Test > Java' 카테고리의 다른 글
백준 단계별 풀이 - 2차원 배열 (0) | 2024.01.01 |
---|---|
백준 단계별 풀이 - 일반 수학1 (1) | 2023.12.31 |
백준 단계별 풀이 - 문자열 (1) | 2023.12.23 |
백준 단계별 풀이 - 반복문, 1차원 배열 (1) | 2023.12.21 |
백준 단계별 풀이 - 입출력과 사칙연산, 조건문 (0) | 2023.12.19 |