문제 ν•΄κ²° (PS)/κΈ°μ–΅ν•΄λ‘˜ 것

2의 제곱수 νŒλ³„, μž‘κ±°λ‚˜ 같은 μˆ˜λ“€ 쀑 κ°€μž₯ 큰 2의 제곱수 κ΅¬ν•˜κΈ°

9taetae9 2024. 1. 17. 15:09
728x90

2의 μ œκ³±μˆ˜μΈμ§€ νŒλ³„ν•˜κΈ°

public class PowerOfTwoChecker {

    public static boolean isPowerOfTwo(int n) {
        return n > 0 && (n & (n - 1)) == 0;
    }

    public static void main(String[] args) {
        System.out.println(isPowerOfTwo(1)); // true
        System.out.println(isPowerOfTwo(2)); // true
        System.out.println(isPowerOfTwo(16)); // true
        System.out.println(isPowerOfTwo(18)); // false
    }
}

 

 

2의 μ œκ³±μˆ˜λŠ” μ΄μ§„μˆ˜λ‘œ ν‘œν˜„ν–ˆμ„ λ•Œ, 1 뒀에 0만 μ—¬λŸ¬ 개 μžˆλŠ” ν˜•νƒœλ₯Ό κ°€μ§„λ‹€. (예: 1, 10, 100, 1000, ...). μ΄λŸ¬ν•œ νŠΉμ„±μ„ ν™œμš©ν•˜μ—¬ μ•„λž˜μ™€ 같은 λ‘œμ§μ„ κ΅¬ν˜„ν•  수 μžˆλ‹€.

 

(n & (n-1)) == 0;

 

μ΄μ§„μˆ˜ 1000μ—μ„œ 1을 λΉΌλ©΄ μ΄μ§„μˆ˜ 0111이 되기 λ•Œλ¬Έμ— 1000 & 0111 == 0 즉, 각자리의 μˆ«μžκ°€ 무쑰건 λ‹¬λΌμ§„λ‹€λŠ” νŠΉμ„±μ΄ μžˆλ‹€. λ”°λΌμ„œ λΉ„νŠΈ and 연산을 μˆ˜ν–‰ν–ˆμ„ λ•Œ 0이 λ‚˜μ˜€κ²Œ λœλ‹€.

 

 

μ£Όμ–΄μ§„ μˆ«μžλ³΄λ‹€ μž‘κ±°λ‚˜ 같은 κ°€μž₯ 큰 2의 제곱수 μ°ΎκΈ° (right shift μ—°μ‚° ν™œμš©)

public static long findLargestPowerOfTwoLessThanOrEqual(long n) {
        n |= n >> 1;
        n |= n >> 2;
        n |= n >> 4;
        n |= n >> 8;
        n |= n >> 16;
        n |= n >> 32;
        return (n + 1) >> 1;
    }

 

μ£Όμ–΄μ§„ 수 보닀 μž‘κ±°λ‚˜ 같은 μˆ˜λ“€ 쀑 κ°€μž₯ 큰 2의 제곱수λ₯Ό μ°ΎκΈ° μœ„ν•΄μ„  μš°μ„  2의 제곱의 νŠΉμ§•μ„ μ•Œμ•„μ•Όν•œλ‹€. μ•žμ—μ„œλ„ λ§ν–ˆλ“―μ΄ 2의 μ œκ³±μˆ˜λŠ” μ΄μ§„μˆ˜λ‘œ ν‘œν˜„ν–ˆμ„ λ•Œ, 1 뒀에 0만 μ—¬λŸ¬ 개 μžˆλŠ” ν˜•νƒœλ₯Ό κ°€μ§„λ‹€. (예: 1, 10, 100, 1000, ...). 

 

κ·Έλž˜μ„œ ν•΄λ‹Ή 수 보닀 κ°™κ±°λ‚˜ μž‘μ€ μˆ˜λ“€ 쀑 κ°€μž₯ 큰 2의 제곱수λ₯Ό κ΅¬ν•˜κΈ° μœ„ν•΄μ„  ν•΄λ‹Ή 수 이진 ν‘œν˜„μ˜ μ΅œμƒμœ„ λΉ„νŠΈ 1을 μ œμ™Έν•œ ν•˜μœ„ λΉ„νŠΈλ“€μ΄ 0이면 λœλ‹€.  

ex) 101101 보닀 μž‘κ±°λ‚˜ 같은 수 쀑 κ°€μž₯ 큰 2의 μ œκ³±μˆ˜λŠ” 100000이 λœλ‹€.

111111 => 100000

10101 => 1000

1010 => 1000

1011 => 1000

 

즉 우리의 λͺ©ν‘œλŠ” μ΅œμƒμœ„ λΉ„νŠΈ 1을 μ œμ™Έν•œ ν•˜μœ„λΉ„νŠΈλ“€μ΄ 0인 수λ₯Ό λ°˜ν™˜ν•˜λŠ” 것이닀.

이λ₯Ό μœ„ν•΄ μš°μ„  μ£Όμ–΄μ§„ 수 n의 μ΅œμƒμœ„ λΉ„νŠΈ 1λΆ€ν„° μ΅œν•˜μœ„ λΉ„νŠΈκΉŒμ§€ λͺ¨λ‘ 1둜 λ§Œλ“ λ‹€.   ex) 1001010 => 1111111

 

이제 μ΅œμƒμœ„ λΉ„νŠΈ 1을 μ œμ™Έν•œ ν•˜μœ„ λΉ„νŠΈ λͺ¨λ“  1듀을 0으둜 λ§Œλ“€μ–΄ μ£Όλ©΄ λ˜λŠ”λ° μ΄λŠ” λ‹¨μˆœνžˆ 1을 더해주면 λœλ‹€.

1111111 + 1 => 10000000

μš°λ¦¬κ°€ μ›ν•˜λŠ” 것은 0이 ν•˜λ‚˜ 적은 μ΄μ§„μˆ˜(1000000)μ΄λ―€λ‘œ right shift 1 (>>1 μ—°μ‚°)을 톡해 ꡬ할 수 μžˆλ‹€.

 

10000000 >> 1 => 1000000

 

 

μ£Όμ–΄μ§„ 수 n의 μ΅œμƒμœ„ λΉ„νŠΈ 1λΆ€ν„° μ΅œν•˜μœ„ λΉ„νŠΈκΉŒμ§€ λͺ¨λ‘ 1둜 λ§Œλ“œλŠ” 과정을 쑰금 더 μžμ„Ένžˆ μ„€λͺ…해보면 

n |= n >> 1;   // 첫 λ‹¨κ³„μ—μ„œ μƒμœ„ 2λΉ„νŠΈκ°€ 1이 λœλ‹€
n |= n >> 2;  // μƒμœ„ 2λΉ„νŠΈκ°€ 1μ΄λ―€λ‘œ 2번 μ‰¬ν”„νŠΈ 연산을 ν•œλ’€ bitwise or 연산을 ν•΄μ£Όλ©΄ μƒμœ„ 4λΉ„νŠΈκ°€ 1μ΄λœλ‹€.
n |= n >> 4;  // μƒμœ„ 4λΉ„νŠΈκ°€ 1μ΄λ―€λ‘œ 4번 μ‰¬ν”„νŠΈ 연산을 ν•΄μ€€λ’€ bitwise or 연산을 ν•΄μ£Όλ©΄ μƒμœ„ 8λΉ„νŠΈκ°€ 1μ΄λœλ‹€.
n |= n >> 8; // μƒμœ„ 8λΉ„νŠΈκ°€ 1μ΄λ―€λ‘œ 8번 μ‰¬ν”„νŠΈ 연산을 ν•΄μ€€λ’€ bitwise or 연산을 ν•΄μ£Όλ©΄ μƒμœ„ 16λΉ„νŠΈκ°€ 1μ΄λœλ‹€.
n |= n >> 16; // μƒμœ„ 16λΉ„νŠΈκ°€ 1μ΄λ―€λ‘œ 16번 μ‰¬ν”„νŠΈ 연산을 ν•΄μ€€λ’€ bitwise or 연산을 ν•΄μ£Όλ©΄ μƒμœ„ 32λΉ„νŠΈκ°€ 1μ΄λœλ‹€.
n |= n >> 32;  // μƒμœ„ 32λΉ„νŠΈκ°€ 1μ΄λ―€λ‘œ 32번 μ‰¬ν”„νŠΈ 연산을 ν•΄μ€€λ’€ bitwise or 연산을 ν•΄μ£Όλ©΄ μƒμœ„ 64λΉ„νŠΈκ°€ 1μ΄λœλ‹€.

 

이λ₯Ό 톡해 μ–‘μˆ˜ long λ²”μœ„(2^63-1 κΉŒμ§€)의 λͺ¨λ“  수λ₯Ό μ»€λ²„ν•˜λ©° μ΅œμƒμœ„ λΉ„νŠΈ 1λΆ€ν„° ν•˜μœ„ λΉ„νŠΈλ“€μ„ λͺ¨λ‘ 1둜 λ§Œλ“€μˆ˜ μžˆλ‹€.

 

 

 

 

μ‘μš©λ¬Έμ œ

 

https://www.hackerrank.com/challenges/counter-game/problem

 

Counter game | HackerRank

Louise and Richard play a game, find the winner of the game.

www.hackerrank.com

 

728x90