이 영역을 누르면 첫 페이지로 이동
쿄코코 블로그의 첫 페이지로 이동

쿄코코

페이지 맨 위로 올라가기

쿄코코

얼레벌레 생활🤯

백준 10819(차이를 최대로)- Python(파이썬),Java(자바) - 구현,브루트포스(Permutations,Combinations,백트래킹,Java- 스택 사용 )

  • 2022.06.09 23:23
  • [백준] Python,Java로 풀기📖/구현
    반응형
     

    10819번: 차이를 최대로

    첫째 줄에 N (3 ≤ N ≤ 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.

    www.acmicpc.net

     

    예제 설명

    일단 배열 A를 오름차순으로 정렬한다. 

    인덱스 0 1 2 3 4 5
    배열 1 4 8 10 15 20

    인덱스의 차이가 최대이기 위해서는 고른 인덱스와 선택하지 않은 배열 중 제일 먼 인덱스를 골라야한다.

    ex ] 0고르기 -> 5고르기 -> 1고르기 -> 4고르기 -> 2고르기 -> 3고르기

    하지만 마지막에 2를 고르고 3을 고르는 것보다 인덱스 3을 제일 앞에 두는 것이 더 차이의 합이 커진다

    ex ] 3고르기 -> 0고르기 -> 5고르기 -> 1고르기 -> 4고르기 -> 2고르기

        1. 처음 인덱스가 0인 경우
          인덱스 3 0 5 1 4 2 차이의 합
          인덱스의 값 10 1 20 4 15 8 9+19+16
          +11+7=62 
        2. 처음 인덱스가 5인 경우
          인덱스 2 5 0 4 1 3 차이의 합
          인덱스의 값 8 20 1 15 4 10 12+19+14
          +11+6=62

    이런식으로 둘이 비교하였을 때 최대인 값이 차이의 합이 최대인 62가 나오게 되었다.

     

    N = 6

       1. 처음 인덱스가 0인 경우

        이 때 고른 인덱스의 경우를 나열하면 ( 3, 0 ), ( 0, 5), ( 5,1 ),  ( 1, 4 ), ( 4, 2 ) 이렇게 다섯가지이다. 이 경우를 분류하면

        ① 인덱스의 합  5(N-1)인 경우 : ( 0, 5 ) ( 1, 4 ) 

        i = 0 -> a[ 5-0 ] - a[ 0 ] 

        i = 1 -> a [ 5-1 ] - a[ 1 ]

        i = 5//2 = 2 -> ( N-1 )을 2로 나눈 몫 전까지 수행

        ② 인덱스의 합 6(N)인 경우 : ( 5,1 ) ( 4,2 ) 

        i = 1 -> a[ 6-1 ] - a[ 1 ]

        i = 2 -> a [ 6-2 ] - a[ 2 ]

        i = 6//2 = 3 -> ( N)을 2로 나눈 몫 전까지 수행

        ③ 예외 : ( 3,0 ) -> 둘의 차이가 3( N//2 )

        : a[n//2] - a[0]

       

       2. 처음 인덱스가 5인 경우

       이 때 고른 인덱스의 경우를 나열하면 ( 2,5 ), ( 5, 0 ), ( 0, 4 ), ( 4, 1 ), ( 1, 3 )이렇게 다섯가지이다. 이 경우를 분류하면

        ① 인덱스의 합  5(N-1)인 경우 : ( 5, 0 ) ( 4, 1 )

        i = 0 -> a[ 5-0 ] - a[ 0 ] 

        i = 1 -> a [ 5-1 ] - a[ 1 ]

        i = 5//2 = 2 -> ( N-1 )을 2로 나눈 몫 전까지 수행

        ② 인덱스의 합 4(N -2)인 경우 : ( 0, 4 ) ( 1, 3 )

        i = 0 -> a[ 4-1 ] - a[ 1 ]

        i = 1 -> a [ 4-2 ] - a[ 2 ]

        i = 4//2 = 2 -> ( N-2 )를 2로 나눈 몫 전까지 수행

        ③ 예외 : ( 2,5 ) -> 둘의 차이가 3( N//2 )

       : a[n-1] - a[n-1 - n//2]

    => ①은 공통이고 ②+③의 최대의 값을 찾아서 sum을 구하면 된다.


    문제풀이

    ① 인덱스의 합이 N-1인경우 : 0부터 시작해서 (N-1)//2 전까지 for문으로 a 배열의 차이( a[ n-1 -i ] - a[ i ] )를 더하기
    ② 인덱스의 합이 N인 경우 : 1부터 시작해서 N//2전까지 for문으로 a배열의 차이( a[n-i] - a[i] )를 더하기
       + ( a[ n// 2 ] - a[ 0 ] ) 
    ③ 인덱스의 합이 N-2인 경우 : 0부터 시작해서 (N-2)//2전까지 for문으로 a배열의 차이( a[ n-2-i ] - a[ i ] )를 더하기
       + ( a[n-1] - a[ n-1 - n//2 ] )
    ④ ②,③의 경우를 비교하여서 큰 값을 ①을 더하기 

    💻Python(파이썬)

    import sys
    n = int(sys.stdin.readline())
    a = list(map(int,sys.stdin.readline().split()))
    #정렬
    a.sort()
    sum=num1=num2 =0
    #1.인덱스의 합이 N-1인 경우
    for i in range((n-1)//2):
        sum+=a[n-1-i]-a[i]
    #2.인덱스의 합이 합이 N인 경우
    for i in range(1,n//2):
        num1 += a[n-i]-a[i]
    num1 += a[n//2]-a[0]
    #3.인덱스의 합이 N-2인 경우
    for i in range(1,(n-2)//2):
        num2 += a[n-2-i]-a[i]
    num2 += a[n-1]-a[n-1-n//2]
    #2번과 3번 비교
    if num1>num2:
        sum+=num1
    else:
        sum+=num2
    
    print(sum)

    💻 Java(자바)

    import java.util.*;
    import java.io.*;
    
    public class Main {
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(br.readLine());
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            int[] a = new int[n];
            for(int i=0;i<n;i++){
                a[i]=Integer.parseInt(st.nextToken());
            }
            Arrays.sort(a);
            int sum =0;
            for(int i=0;i<(n-1)/2;i++){
                sum+=a[n-1-i]-a[i];
            }
            int num1=0,num2=0;
            for(int i=1;i<n/2;i++){
                num1 += a[n-i]-a[i];
            }
            num1 += a[n/2]-a[0];
            for(int i=0;i<(n-2)/2;i++){
                num2+= a[n-2-i]-a[i];
            }
            num2 += a[n-1]-a[n-1-n/2];
            if(num1>num2){
                sum+=num1;
            }else{
                sum+=num2;
            }
            System.out.println(sum);
        }
    }

    📌 파이썬 Permutation 사용 

     Python( 파이썬 )

    참고 자료 : https://velog.io/@dramatic/Python-permutation-combination-순열과-조합

      📖 permutations : 순열 라이브러리(nPr)

    - 서로 다른 n개 중에서 r개를 골라 순서를 나열하는 가짓수

    from itertools import permutations
    
    arr = [ 'A', 'B', 'C' ]
    #('A', 'B', 'C') ('A', 'C', 'B') ('B', 'A', 'C') ('B', 'C', 'A') ('C', 'A', 'B') ('C', 'B', 'A')
    nP3 = permutations(arr) #arr의 가짓수
    #('A', 'B') ('A', 'C') ('B', 'A') ('B', 'C') ('C', 'A') ('C', 'B')
    nP2 = permutations(arr,2) #arr에서 2개의 원소를 골라 나열하는 가짓수
    #('A')('B')('C')
    nP1 = permutations(arr,1) #arr에서 1개의 원소를 골라 나열하는 가짓수

      📖 combinations : 조합 라이브러리(nCr)

    - 서로 다른 n개 중에서 r개를 뽑는 경우의 수

    - 조합의 경우는 순서를 신경쓰지 않고 누구를 뽑았는지 중요

    from itertools import combinations
    
    arr = [ 'A', 'B', 'C' ]
    #('A', 'B', 'C')
    nC3 = combinations(arr,3) #arr의 가짓수
    #('A', 'B') ('A', 'C') ('B', 'C')
    nC2 = combinations(arr,2) #arr에서 2개의 원소를 고르는 가짓수
    #('A')('B')('C')
    nC1 = combinations(arr,1) #arr에서 1개의 원소를 고르는 가짓수
    for i in nC3:
        print(i,end=" ")
    for i in nC2:
        print(i,end=" ")
    for i in nC1:
        print(i,end=" ")

    문제 풀이

    ① 배열이 나열 될 수 있는 전체 가짓수 n!를 저장
    ② 입력 받은 배열을 하나씩 차이의 sum 값을 계산하고 전에 구한 값보다 지금 구한 sum값이 클 경우 변경
    ③ 최종 최댓값 출력 

    💻 Python(파이썬) - Permutation 라이브러리 사용

    import sys
    #순열
    from itertools import permutations
    
    n = int(sys.stdin.readline())
    array = list(map(int,sys.stdin.readline().split()))
    
    #배열의 가짓수
    nPr = permutations(array)
    #가장 큰 배열 초기화
    max_sum=0
    #배열마다 하나씩 실행 
    for arr in nPr:
        sum=0
        #배열 하나마다 차이의 sum 값 구하기
        for j in range(len(arr)-1):
            sum+=abs(arr[j]-arr[j+1])
        #만약 전에 구한 값보다 지금 구한 sum이 크면
        if max_sum<sum:
            max_sum = sum
    
    print(max_sum)

    📌  Permutation 사용하지 않고 백트래킹으로 구하기

    문제 풀이

    ① 백트래킹 함수(x) 함수를 구현
       - temp : 인덱스 숫자를 담는 배열 ( ex. [0 1 2 3] -> 0,1,2,3 인덱스 )
       - x : 백트래킹 함수의 인수로 temp에 담긴 개수는 x을 의미
       - if x==n 은 temp에 모든 숫자가 담겼다는 의미로 배열[temp의 숫자]를 for문으로 돌려서 차이의 합을 구해야한다
         이 값이 전에 값이랑 비교해서 큰 경우 답에 적기

    백트래킹은 이해가 되었는데 코드를 봤더니 이해가 되지 않아서 코드 하는 방법을 좀 적어보았다.

     

    부연 설명 펼쳐보기

    더보기

     1. sol[0]를 실행해서 [0]을 집어넣고 pop을 하기 전에 재귀함수를 호출해서 sol[0+1]를 호출

    2. sol[1]를 실행해서 [0 1]을 집어넣고 pop을 하기 전에 재귀함수를 호출해서 sol[1+1]를 호출

     

    3. sol[2]를 실행해서 [0 1 2]을 집어넣고 pop을 하기 전에 재귀함수를 호출해서 sol[2+1]를 호출

    4.sol[3]를 실행해서 [0 1 2 3]을 집어넣고 pop하기 전에 재귀함수를 호출해서 백트래킹 함수(sol[3+1])를 호출

     

    5.sol[4]를 실행해서 [0 1 2 3 4]을 집어넣고 pop하기 전에 재귀함수를 호출해서 백트래킹 함수(sol[4+1])를 호출

     

    6.sol[5]를 실행해서 [0 1 2 3 4 5]을 집어넣고 pop하기 전에 재귀함수를 호출해서 백트래킹 함수(sol[5+1])를 호출

    7.sol[6]을 실행하는데 6==N이랑 동일하므로 if문 실행해서 차이를 구하고 종료 -> sol[5]의 pop 하러 가기

    8. sol[5] pop을 하였기에 [0 1 2 3 4]하고 종료 -> sol[4]의 pop하러가기

    9.sol[4]의 pop을 하였기에 [0 1 2 3]하고 i=5하기 -> i=5가 없기에 5를 집어넣고 [0 1 2 3 5] 재귀함수 호출해서 sol[4+1] 호출

    10. sol[5]를 실행하는데 i=4 인덱스가 없으므로 [0 1 2 3 5 4]로 append하고 pop하기 전에 재귀함수 sol[5+1]을 호출

    11.so[6]을 실행하는데 6==N이랑 동일하므로 If문 실행해서 아까 7번에서 구한 값과 비교하여 큰값을 저장 -> sol[5] pop하러 가기

    12. sol[5]의 pop을 하였기에 [0 1 2 3 5]에서 i=5를 실행하는데 이미 인덱스 5가 있으므로 종료

    13. sol[3]의 pop을 하여서 [0 1 2 3]에서 i=4 실행

    ..........

    코드 참고 자료 : https://fre2-dom.tistory.com/442

    💻 Python(파이썬) - Permutation 라이브러리 사용하지 않고 재귀함수 백트래킹

    import sys
    
    
    def sol(x):
        global answer
        # x가 n개라면 => x == len(temp)
        # 조건에 맞게 수를 더해준다.
        if x == n:
            total=0
            #차이의 합을 구하기
            total = sum(abs(m[temp[i + 1]] - m[temp[i]]) for i in range(n - 1))
            #이전에 구한 합과 비교해서 큰값을 저장
            answer = max(total,answer)
            return
    
        # 반복문을 통해 idx를 temp에 저장
        for i in range(n):
            if i not in temp:
                temp.append(i)
                sol(x + 1) # 백 트래킹
                temp.pop()
    
    
    n = int(sys.stdin.readline())
    m = list(map(int, sys.stdin.readline().split()))
    #차이의 합
    answer = 0
    #배열의 인덱스의 값
    temp = []
    sol(0)
    
    print(answer)

    💻 Java(자바)  -> Python과 동일한 방법으로 temp를 pop 사용

    참고 자료 : https://wakestand.tistory.com/197

    * 스택 선언 - Stack<Integer> temp = new Stack<Integer>();

    * 스택 인덱스 확인 temp.elementAt(i) : i번째 인덱스 확인

    * 스택 안에 특정 값있는지 확인 temp.indexof(i): i가 스택안에 들었는지 확인

    * 스택 안에 넣기 temp.push(i) -> 스택 temp안에 i 넣기

    import java.util.*;
    import java.io.*;
    
    public class Main {
        static int sum =0;
        static int n;
        static int[] array;
        static Stack<Integer> temp = new Stack<>();
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            n = Integer.parseInt(br.readLine());
            array = new int[n];
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            for(int i=0;i<n;i++){
                array[i] = Integer.parseInt(st.nextToken());
            }
            sol(0);
            System.out.println(sum);
        }
        static void sol(int x){
            if(x==n){
                int total = 0;
                for(int i=0;i<n-1;i++){
                    //스택 인덱스 확인
                    total += Math.abs(array[temp.elementAt(i+1)]- array[temp.elementAt(i)]);
                }
                if(total>sum){
                    sum = total;
                }
                return;
            }
            for(int i=0;i<n;i++){
                if(!temp.contains(i)){
                    temp.push(i);
                    sol(x+1);
                    temp.pop();
                }
            }
        }
    }

    💻 Java(자바) -> visted로 포함한 함수인지 확인하는 법

    import java.util.*;
    import java.io.*;
    
    public class Main {
        static int sum =0;
        static int n;
        static int[] array,temp;
        static boolean[] visted;
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            n = Integer.parseInt(br.readLine());
            array = new int[n];
            temp = new int[n];
            visted=new boolean[n];
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            for(int i=0;i<n;i++){
                array[i] = Integer.parseInt(st.nextToken());
            }
            sol(0);
            System.out.println(sum);
        }
        static void sol(int x){
            if(x==n){
                int total = 0;
                for(int i=0;i<n-1;i++){
                    total += Math.abs(array[temp[i+1]]- array[temp[i]]);
                }
                if(total>sum){
                    sum = total;
                }
                return;
            }
            for(int i=0;i<n;i++){
                if(!visted[i]){
                    visted[i]=true;
                    temp[x]=i;
                    sol(x+1);
                    visted[i]=false;
                }
            }
        }
    }

     

    반응형

    '[백준] Python,Java로 풀기📖 > 구현' 카테고리의 다른 글

    백준 2578(빙고) - 구현  (0) 2025.04.11
    백준 1913(달팽이) - Python(파이썬) - 구현  (0) 2022.06.06
    백준 2232(지뢰) - 구현  (0) 2022.05.25

    댓글

    이 글 공유하기

    • 구독하기

      구독하기

    • 카카오톡

      카카오톡

    • 라인

      라인

    • 트위터

      트위터

    • Facebook

      Facebook

    • 카카오스토리

      카카오스토리

    • 밴드

      밴드

    • 네이버 블로그

      네이버 블로그

    • Pocket

      Pocket

    • Evernote

      Evernote

    다른 글

    • 백준 2578(빙고) - 구현

      백준 2578(빙고) - 구현

      2025.04.11
    • 백준 1913(달팽이) - Python(파이썬) - 구현

      백준 1913(달팽이) - Python(파이썬) - 구현

      2022.06.06
    • 백준 2232(지뢰) - 구현

      백준 2232(지뢰) - 구현

      2022.05.25
    다른 글 더 둘러보기

    정보

    쿄코코 블로그의 첫 페이지로 이동

    쿄코코

    • 쿄코코의 첫 페이지로 이동

    검색

    메뉴

    • 홈

    카테고리

    • 분류 전체보기 (172)
      • Python (24)
        • 😈 99클럽 코테 스터디 4기 TIL (23)
        • 궁금한거 정리 (1)
      • SQL (16)
        • HackerRank (15)
      • [백준] Python,Java로 풀기📖 (71)
        • 정렬(Sorting) (6)
        • 그리디 (5)
        • 문자열 (7)
        • 수학 (3)
        • DFS&BFS (10)
        • 구현 (4)
        • 다이나믹 (17)
        • 이분탐색 (1)
        • 자료구조 (10)
        • 최단거리 (5)
        • 인덱스트리 (0)
      • [프로그래머스]Python,Java로 풀기 (6)
        • Level 1 (4)
        • Level 2 (2)
      • Study Platform📚 (28)
        • 김영한👨🏻‍🏫의 스프링 부트와 JPA 실무 완전 .. (5)
        • (알고리즘)- [이코테] 이것이 코딩테스트다 정리 (10)
        • 그림으로 배우는 Http&Network Basic (10)
        • AWS SAA C03공부하기 (3)
      • 까먹을까봐 적는 것들 (5)
      • 테스트 보고 난 후..🤔 (0)
      • kt 에이블스쿨 (18)

    최근 글

    인기 글

    댓글

    공지사항

    아카이브

    태그

    • TiL
    • 오블완
    • 백준
    • 티스토리챌린지
    • 프로그래머스
    • 항해99
    • 99클럽
    • 코딩테스트준비

    나의 외부 링크

    정보

    쿄코코의 쿄코코

    쿄코코

    쿄코코

    블로그 구독하기

    • 구독하기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. © 쿄코코. Designed by Fraccino.

    티스토리툴바