본문 바로가기
알고리즘/백준

10250번 문제 : ACM호텔

by son_i 2023. 3. 13.
728x90

10250번: ACM 호텔 (acmicpc.net)

 

10250번: ACM 호텔

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수

www.acmicpc.net

생각보다 간단하게 만들었는데 계속해서 수정을 거쳤다.

 

package algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args) throws  IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int num = Integer.parseInt(br.readLine());
		int input[][] = new int[num][3];
		int count=0;
		StringBuilder sb= new StringBuilder();
		int h=0;
		int w=0;
		int n=0;
		String result[] = new String[num];
		int search = 0;
		for(int i=0;i<num;i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			input[i][0] = Integer.parseInt(st.nextToken());
			input[i][1] = Integer.parseInt(st.nextToken());
			input[i][2] = Integer.parseInt(st.nextToken());
		}
		for(int k=0;k<num;k++) {
			h=input[k][0] ;
			w=input[k][1];
			n=input[k][2];

			for(int i=1;i<=w;i++) {
				for(int j=1;j<=h;j++) {
					count++;
					if(count == n) {
						if(i<10) 
							result[k] = j+"0"+i;
						else
						result[k] = j+""+i;
			
						search=1;
						count=0;
						break;
					}
				}
				if(search == 1) {
					sb.append(result[k]).append("\n");
					search=0;
					break;
				}
			}		
		}
		System.out.println(sb);
	}
}

먼저 입력받은 값을 2차원 배열 0,1,2 번째에 h,w,n 순서대로 넣고 3중첩 for문을 돌아서 count로 n번째 도착한 손님을 찾는다. 호실은 엘리베이터랑 가까운 순대로 101 201 301 ...... (h만큼) 그리고 102 202 ,,, 이런식으로 가니까 h를 안쪽 for문에 넣었다.

1. for (사람만큼 반복(변수 k=0부터 시작){

    2. for(w만큼 반복(변수 i=1부터 시작)){

        3. for(h만큼 반복(변수 j=1부터 시작)){

           count++; //0으로 초기화 되어있다가 호실을 지날 때마다 +1을 해서 N번째 손님이 배정될 곳을 찾음

           if(count == n){ //배정될 호실을 찾았으면

              if(i<10) //맨 끝자리 호수가 10미만이면 101 209 이런식으로 층과 호수 사이에 0이 들어가야함

                  result[k] = j+"0"+i;

              else

                  result[k] = j+""+i;

              search=1; //search라는 변수를 두어서 찾았으면 1 대입

              count =  0; 

              break; //제일 안 쪽 3. for문 빠져나감

           }

           if(search == 1) { //호실을 찾았다면

           sb.append(result[k]).append("\n"); //StringBuilder에 넣어줌

           search = 0; //호실을 찾았다는 의미의 search를 0으로 바꿔줌

           break; //2.for문 빠져나감

           }

        } //1. 사람 명수만큼 같은 과정 반복

    }

} System.out.println(sb); // 그러고 출력

 


해결은 했는데 코드가 너무 복잡해보인다. 더 간단한 방법을 찾아보자 !

배치되는 순서는 

 

4 8 12 16 20(405)
3(301) 7(302) 11(303) 15(304) 19(304)
2(201) 6(202) 10(203) 14(204) 18
1(101) 5(102) 9(103) 13(104) 17

이런식 ( HXW == 4X5) H == 4, W == 5

방번호는 YYX . Y는 층수 X는 엘리베이터로부터 떨어진 거리 엘리베이터는 1234 좌측에 있음

1. Y(층) 구하기 

입력으로 들어오는 H값을 이용. N번째 손님과 H는 어떻게 연산하여 층수를 나타낼까?

N을 H로 나눈 나머지값이 층수 ex) 19번째 손님 H==4  층수는 

int Y = N % H;

3층이다. 근데 만약에 20번째 손님이라면 나머지가 0이되어버리는데 그때는 H가 층수이다.

N%H == 20 % 4 == 0   -> 4층

 

이렇게 조건문을 달아보면

if(n%h == 0) {
				y = h;
			}else y=n%h;

그리고 호수는 YYX 또는 YYXX 로 최소 100의 자리부터 시작하니까 층수에 *100을 해줘야한다.

 

2. X(호수) 구하기

N번째 손님을 건물 층수(h)로 나눈 몫이 엘리베이터로부터 떨어진 거리. +1을 해줘야함.

ex) N이 4이고 H=5일때 나눗셈을 하면 몫이 0이지만 X(호수)는 1부터 시작하기 때문에

따라서 int X = (N/H) +1;

 여기서도 N=6이고 H=6이면 601호. 몫이 1 이때는 +1을 해주지않고 그냥(N/h).

if( (N%h) ==0)
	X = N/h;
else N/h +1;

Y와 X의 예외조건이 같으므로 하나로 합친다.

 

여기서 w는 쓸 필요가 없다. N이 H*W의 값보다 크게 주어지지가 않기 때문.

그래서 정리하면

package algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args) throws  IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int num = Integer.parseInt(br.readLine());
		int input[][] = new int[num][3];
		StringBuilder sb= new StringBuilder();
		int X=0;
		int Y=0;
		int h=0;
		int w=0;
		int n=0;
		for(int i=0;i<num;i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			input[i][0] = Integer.parseInt(st.nextToken());
			input[i][1] = Integer.parseInt(st.nextToken());
			input[i][2] = Integer.parseInt(st.nextToken());
		}
		for(int i=0;i<num;i++) {
			h = input[i][0];
			w = input[i][1];
			n = input[i][2];
			if(n % h==0){//층수구하기
				Y=h*100;
				X = n/h;
			}
			else
			{
				Y=(n%h)*100;
				X = (n/h)+1;
			}
			sb.append(Y+X).append("\n");
		}
		System.out.println(sb);
	}
}

이렇게 만들 수 있는데 여기서 배열도 필요가 없다.

57364174 w입력을 변수에 저장 안 하고 그냥 nextToken으로 날려버림 sb로 출력

57364092 Sysout을 StringBuilder로 변경

57363884 int X Y 변수 선언을 없애고 바로 출력했는데 System.out.print로 출력

57363747 배열을 없앴는데 시간차이가 크지않음  sb로 출력

57363614 위에 풀이법으로 층수와 호수를 구해서 풀었더니 시간 단축 sb로 출력

57359052 내가 푼 코드 시간이 젤 오래 걸림

 

StringBuilder가 시간 단축에 압도적이네 !

package algorithm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main{
	public static void main(String[] args) throws  IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int num = Integer.parseInt(br.readLine());
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<num;i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			int h = Integer.parseInt(st.nextToken());
			st.nextToken();
			int n = Integer.parseInt(st.nextToken());
			
			if(n % h==0)//층수구하기
				sb.append(h*100+n/h).append("\n");
			else
				sb.append((n%h)*100 +((n/h)+1)).append("\n");
		}
		System.out.println(sb);
	}
}

최종코드 휴 .. ㅋ

 

728x90

'알고리즘 > 백준' 카테고리의 다른 글

1259번 문제 : 팰린드롬수  (0) 2023.03.17
1018번 문제 : 체스판 다시 칠하기  (0) 2023.03.16
10814번 문제 : 나이순 정렬  (0) 2023.03.12
7568번 문제 : 덩치  (0) 2023.03.11
4153번 문제 : 직각삼각형  (0) 2023.03.10