수 묶기(백준 1744번)

2023. 1. 8. 16:27·BackEnd/알고리즘 공부

https://www.acmicpc.net/problem/1744

 

1744번: 수 묶기

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에

www.acmicpc.net

 

문제 설명

-1 -8 2 1 3 6 -5 0 1 이 주었다고 가정하자. 

(-8 * -5) + (-1 * 0) + 1 + 1 + 2 + (3 * 6)  = 62 이다.

 

문제에 대한 아이디어

이 문제는 그리디 알고리즘으로 풀어야 하는 이유가 매 순간 제일 최대의 값을 구해야 하기 때문이다. 

 

실패한 아이디어

제일 처음 문제를 풀 때는 엄청 간단하게 생각했다.

오름차순으로 배열을 정렬 시킨 뒤 맨 뒤에서 부터 2개씩 묶어서 더하도록 만들었다. (선택 절차)

 

문제점

  • 양수와 음수를 곱하게 된다.
  • 수열에 0이 존재하면 0과 양수를 곱하게 된다.
  • 수열에 1이 존재한다면 1은 그냥 더하는 것이 곱하는 것보다 값을 더 크게 만든다.

 

성공한 아이디어

위에 문제점을 토대로 보완한 해결책이다.

  • 우선순위 큐를 사용하여 양수와 음수를 따로 보관하자.
  • 우선순위 큐의 양수 부분은 내림차순으로 설정, 우선순위 큐의 음수 부분은 오름차순으로 설정
  • 0과 1도 따로 생각해자.
  • 양수 부분은 우선순위 큐에서 2개를 빼 곱한뒤 결과값에 더하자.(반복)
  • 만약 양수 부분에 수가 남았으면 결과값에 더한다.
  • 음수 부분은 우선순위 큐에서 2개를 빼 곱한뒤 결과값에 더하자.(반복)
  • 만약 음수 부분에 수가 남았고 0이 존재하면 그 수는 결과값에 더하지 않는다. 

 

구현

  • 우선순위 큐 
PriorityQueue<Integer> plusPq = new PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> minusPq = new PriorityQueue<>();
int one =0;
int zero =0;
for (int i = 0; i < n; i++) {
    int num = sc.nextInt();
    if(num > 1) plusPq.add(num);  //1을 제외한 양수 부분
    else if(num == 1) one++; // 1
    else if(num == 0) zero++; // 0
    else if(num < 0) minusPq.add(num); //음수 부분
}
  • 양수 부분
//양수부분
while(plusPq.size()>1){
    int first = plusPq.poll();
    int second = plusPq.poll();
    result += first * second;
}
if(!plusPq.isEmpty()){
    result += plusPq.poll();
}
  • 음수 부분
//음수부분
while(minusPq.size()>1){
    int first = minusPq.poll();
    int second = minusPq.poll();
    result += first * second;
}
if(!minusPq.isEmpty()){
    if(zero != 0){
        result += 0 * minusPq.poll();
        --zero;
    }
    else result += minusPq.poll();

 

전체 코드

import java.util.Collections;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n= sc.nextInt();
        PriorityQueue<Integer> plusPq = new PriorityQueue<>(Collections.reverseOrder());
        PriorityQueue<Integer> minusPq = new PriorityQueue<>();
        int one =0;
        int zero =0;
        for (int i = 0; i < n; i++) {
            int num = sc.nextInt();
            if(num > 1) plusPq.add(num);  //1을 제외한 양수 부분
            else if(num == 1) one++; // 1
            else if(num == 0) zero++; // 0
            else if(num < 0) minusPq.add(num); //음수 부분
        }
        int result =0;

        //양수부분
        while(plusPq.size()>1){
            int first = plusPq.poll();
            int second = plusPq.poll();
            result += first * second;
        }
        if(!plusPq.isEmpty()){
            result += plusPq.poll();
        }

        //음수부분
        while(minusPq.size()>1){
            int first = minusPq.poll();
            int second = minusPq.poll();
            result += first * second;
        }
        if(!minusPq.isEmpty()){
            if(zero != 0){
                result += 0 * minusPq.poll();
                --zero;
            }
            else result += minusPq.poll();
        }
        result += one;
        System.out.println(result);
    }
}

 

'BackEnd > 알고리즘 공부' 카테고리의 다른 글

빙산(백준_2573)  (0) 2023.01.13
K번째 수(백준 1300번)  (0) 2023.01.10
탐욕 알고리즘(Greedy Algorithm)  (0) 2023.01.08
트리의 순회(백준_2263)  (0) 2023.01.05
테트로미노(백준_14500)  (0) 2023.01.03
'BackEnd/알고리즘 공부' 카테고리의 다른 글
  • 빙산(백준_2573)
  • K번째 수(백준 1300번)
  • 탐욕 알고리즘(Greedy Algorithm)
  • 트리의 순회(백준_2263)
인프라 감자
인프라 감자
  • 인프라 감자
    삶은 인프라
    인프라 감자
  • 전체
    오늘
    어제
    • 분류 전체보기 (243)
      • 클라우드&인프라 (28)
        • 인프라 공부 (4)
        • AWS 구조와 서비스 (18)
        • 클라우드 공부 (4)
        • Terraform (2)
      • AWS Cloud School (13)
        • project (5)
        • Linux, Network (6)
        • Docker (2)
      • BackEnd (162)
        • JAVA 공부 (15)
        • 알고리즘 공부 (71)
        • MySQL 문제 풀기 (8)
        • 스프링 핵심 원리 - 기본편 (18)
        • 스프링 MVC 1편 (4)
        • 자바 ORM 표준 JPA 프로그래밍 (21)
        • 실전! 스프링 부트와 JPA 활용1 (8)
        • 실전! 스프링 부트와 JPA 활용2 (5)
        • 스프링 데이터 JPA (8)
        • Querydsl (4)
      • 혼자하는 프로젝트 (32)
        • 배달의 민족 클론코딩 (7)
        • 나만의 프로젝트 (10)
        • 스프링 부트로 구현한 웹 (15)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Email
    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    유니온 파인드
    자바
    조합
    쿼드 압축
    상속
    자동 배포
    정렬
    querydsl
    백트래킹
    다이나믹 프로그래밍
    스프링 핵심 원리-기본편
    중첩 선언
    디팬스 게임
    이것이 자바다
    네트워크 기본 용어
    dp
    VPN
    완전탐색
    linux
    프로그래머스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
인프라 감자
수 묶기(백준 1744번)
상단으로

티스토리툴바