[코딩테스트] 가장 가까운 같은 글자, 푸드파이트 대회 - 레벨 1

단비·2023년 3월 25일
0

코딩테스트

목록 보기
2/3

1. 가장 가까운 같은 글자 - Lv.1

  • 문제 설명
    문자열 s가 주어졌을 때, s의 각 위치마다 자신보다 앞에 나왔으면서, 자신과 가장 가까운 곳에 있는 같은 글자가 어디 있는지 알고 싶습니다.
    예를 들어, s="banana"라고 할 때, 각 글자들을 왼쪽부터 오른쪽으로 읽어 나가면서 다음과 같이 진행할 수 있습니다.

    • b는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
    • a는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
    • n은 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
    • a는 자신보다 두 칸 앞에 a가 있습니다. 이는 2로 표현합니다.
    • n도 자신보다 두 칸 앞에 n이 있습니다. 이는 2로 표현합니다.
    • a는 자신보다 두 칸, 네 칸 앞에 a가 있습니다. 이 중 가까운 것은 두 칸 앞이고, 이는 2로 표현합니다.

    따라서 최종 결과물은 [-1, -1, -1, 2, 2, 2]가 됩니다.

    문자열 s이 주어질 때, 위와 같이 정의된 연산을 수행하는 함수 solution을 완성해주세요.

  • 제한사항

    1. 1 ≤ s의 길이 ≤ 10,000
    2. s은 영어 소문자로만 이루어져 있습니다.
  • 문제 풀이

      public class Main {
          public static void main(String[] args) {
              Scanner sc = new Scanner(System.in);
              System.out.println("문자열을 입력하세요:");
              String s = sc.nextLine();
              if(1 > s.length() || s.length() > 10000) { // 제한사항에 부합하지 않을 경우
                  System.out.println("1 ≤ s의 길이 ≤ 10,000 로 입력해주세요.");
                  main(args); // 재실행
              }
              if(s.matches("[^a-z]+")){ // 정규표현식을 이용해 소문자 외 글자가 들어갔는지 체크
                  System.out.println("소문자만 입력해주세요.");
                  main(args); // 재실행
              } else{
                  solution(s); // 아니면 메소드 실행
              }
          }
          public static int[] solution(String s) {
              int[] answer = new int[s.length()]; // return 배열 길이 설정
              for(int i = 0; i < s.length(); i++){ // s 길이만큼 반복
                  if(i == 0) answer[0] = -1; // i가 0일 때 -1 삽입
                  else{
                      boolean result = false; // 같은 값이 있는지 없는지
                      for(int a = i-1; a >= 0; a--){ // 현재 길이만큼 반복문 실행
                          if(s.charAt(a) == s.charAt(i)){ // s의 인덱스 i 이전까지 동일한 문자가 있을 경우
                              answer[i] = i - a; // i번째에 동일한 문자까지의 거리 삽입
                              result = true; // if문 실행하지 않게 true로 변경
                              break;
                          }
                      }
                      if(!result) answer[i] = -1; // 같은 문자가 없을 경우 -1 삽입
                  }
              }
              return answer;
          }
      }

2. 푸드파이트 대회

  • 문제 설명
    수웅이는 매달 주어진 음식을 빨리 먹는 푸드 파이트 대회를 개최합니다. 이 대회에서 선수들은 1대 1로 대결하며, 매 대결마다 음식의 종류와 양이 바뀝니다. 대결은 준비된 음식들을 일렬로 배치한 뒤, 한 선수는 제일 왼쪽에 있는 음식부터 오른쪽으로, 다른 선수는 제일 오른쪽에 있는 음식부터 왼쪽으로 순서대로 먹는 방식으로 진행됩니다. 중앙에는 물을 배치하고, 물을 먼저 먹는 선수가 승리하게 됩니다.

    이때, 대회의 공정성을 위해 두 선수가 먹는 음식의 종류와 양이 같아야 하며, 음식을 먹는 순서도 같아야 합니다. 또한, 이번 대회부터는 칼로리가 낮은 음식을 먼저 먹을 수 있게 배치하여 선수들이 음식을 더 잘 먹을 수 있게 하려고 합니다. 이번 대회를 위해 수웅이는 음식을 주문했는데, 대회의 조건을 고려하지 않고 음식을 주문하여 몇 개의 음식은 대회에 사용하지 못하게 되었습니다.

    예를 들어, 3가지의 음식이 준비되어 있으며, 칼로리가 적은 순서대로 1번 음식을 3개, 2번 음식을 4개, 3번 음식을 6개 준비했으며, 물을 편의상 0번 음식이라고 칭한다면, 두 선수는 1번 음식 1개, 2번 음식 2개, 3번 음식 3개씩을 먹게 되므로 음식의 배치는 "1223330333221"이 됩니다. 따라서 1번 음식 1개는 대회에 사용하지 못합니다.

    수웅이가 준비한 음식의 양을 칼로리가 적은 순서대로 나타내는 정수 배열 food가 주어졌을 때, 대회를 위한 음식의 배치를 나타내는 문자열을 return 하는 solution 함수를 완성해주세요.

  • 제한사항

    1. 2 ≤ food의 길이 ≤ 9
    2. 1 ≤ food의 각 원소 ≤ 1,000
    3. food에는 칼로리가 적은 순서대로 음식의 양이 담겨 있습니다.
    4. food[i]는 i번 음식의 수입니다.
    5. food[0]은 수웅이가 준비한 물의 양이며, 항상 1입니다.
    6. 정답의 길이가 3 이상인 경우만 입력으로 주어집니다.
  • 코드 풀이

      public class Main {
          public static void main(String[] args) {
              Scanner sc = new Scanner(System.in);
              List<Integer> food = new ArrayList<>(); // 음식을 담을 리스트
              food.add(0, 1); // 물의 갯수 추가
              while(true){ // 무한 반복문을 통해 입력값 받기
                  System.out.println("음식의 개수를 입력하세요(현재 " + (food.size()-1) + "종류 / 종료는 0 입력):");
                  int i = sc.nextInt();
                  if(i != 0){ // 종료키인 0이 아닐 경우
                      if(1 <= i && i <= 1000){ // 제한사항에 부합할 경우
                          food.add(i); // 입력 받은 값을 추가
                          if(food.size() == 9) { // 제한사항인 9가지를 전부 넣었을 경우 종료
                              System.out.println("음식 종류 9개 달성으로 종료합니다.");
                              break;
                          }
                      } else{ // 제한사항에 부합하지 않을 경우
                          System.out.println("조건 확인 필요: 1 ≤ food의 각 원소 ≤ 1,000");
                      }
                  } else {
                      if(food.size() > 1) break; // 한가지 이상 추가 후 0을 입력했을 경우
                      else System.out.println("음식 종류 1개 이상 입력해야 종료할 수 있습니다."); // 한가지 이상 추가하지 않고 0을 입력했을 경우
                  }
              }
              int[] result = new int[food.size()]; // 매개변수용 배열은 List 사이즈로 지정
              for(int i = 0; i < food.size(); i++){
                  result[i] = food.get(i); // 순서대로 담기
              }
              solution(result); // 최종적으로 메소드 실행
          }
          public static String solution(int[] food) {
              String answer = "";
              for(int i=1; i < food.length; i++){ // 담긴 종류만큼 반복문 실행
                  if(food[i] >= 2){ // 2보다 클 경우 실행
                      for(int a = 1; a <= food[i] / 2; a++){
                          answer += i; // 리턴 값에 /2 몫만큼 추가
                      }
                  }
              }
              String plus = "";
              for(int a = answer.length()-1; a >= 0; a--){
                  plus += answer.charAt(a); // 거꾸로 담기
              }
              answer += 0 + plus; // 최종적으로 합치기
              return answer;
          }
      }
profile
tistory로 이전! https://sweet-rain-kim.tistory.com/

0개의 댓글