HackerRank/Algorithms

[HackerRank] Implementation > Drawing Book

ruming 2021. 8. 8. 20:12

n은 책의 총 페이지 수, p는 페이지다. p라는 페이지를 펼 때, 처음에서 피는 것과 끝에서(n페이지) 피는 것 중에 덜 피는 것을 고르면 된다. 몇 장을 넘겨야 하는지를 비교해 작은 값을 리턴한다.

 

1페이지가 오른쪽에서부터 시작한다.

방법을 생각하면서 정형화된 공식이 있을까 고민해봤는데 그냥 몇가지 케이스로 나누기로 했다.

짝수일 때와 홀수일 때를 주로 구분했다.

 

 1 | 2 3 | 4 5 | 6 7 | 8 9 | 10 11 | ···

 

일단 첫페이지부터 p까지 넘겨야 되는 경우, 넘겨야 하는 장수는 무조건 p를 2로 나눈 값이 된다. (나머지는 버림)

그리고 p가 홀수면, p를 1페이지로 생각하고 n을 p로 생각해 계산했다. n-p+1한 값에서 2로 나눈다.

 

처음에는 장수를 계산해 비교하지 않고 n-p한 값, p-1한 값을 비교해 더 작은걸로 장수를 세는 방법을 생각했는데, 차가 1이라도 장수가 0일때와 1일때가 달라 그 예외처리가 복잡할 것 같아 이 방법을 사용했다.

 

첫번째 코드

int pageCount(int n, int p) {
    int f, e;
    f = p/2;
    if(p%2==0){
        e = (n-p)/2;
    }else{
        if(n%2==0){
            e = (n-p)/2 + 1;
        }else{
            e = (n-p)/2;
        }
        if(n==p)    e=0;
    }
    if(f<e) return f;
    else    return e;
}

f는 1에서 p까지 넘기는 장수, e는 n에서 p까지 넘기는 장수다. f는 p/2로 계산.

p가 짝수일 때는 (n-p)를 2로 나눈다. 홀수일 때는 n을 또 짝수와 홀수로 나눠서 계산했었는데, 이거는 풀면서 n과 p가 홀짝이 서로 다를 때 생기는 +1을 처리하기 위해 생각한건데, 그럴 필요 없이 n-p+1을 해주면 p를 1페이지로, n을 p로 보고 계산할 수 있다는 것을 깨달아서 아래에 코드를 하나 더 첨부한다.

f와 e중 더 작은 것을 리턴한다.

 

두번째 코드

int pageCount(int n, int p) {
    int f, e;
    f = p/2;
    if(p%2==0){
        e = (n-p)/2;
    }else{
        e = (n-p+1)/2;
    }
    if(f<e) return f;
    else    return e;
}