레벨업 일지

[Java/Python3] 백준 25947. 선물할인 본문

알고리즘/백준

[Java/Python3] 백준 25947. 선물할인

24시간이모자란 2023. 1. 18. 00:45

문제

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

 

25947번: 선물할인

입력은 표준입력을 사용한다. 첫 번째 줄에 선물의 개수를 나타내는 양의 정수 $n$ ($1 ≤ n ≤ 100\,000$), 예산을 나타내는 양의 정수 $b$ ($1 ≤ b ≤ 10^9$), 반값 할인을 받을 수 있는 최대 선물의 수를

www.acmicpc.net

조건을 만족하며 최대로 살 수 있는 선물의 수를 출력한다.

 

 

풀이

 

풀이는 다음과 같다.  int left, right 를 선언해주어 left .. right 범위 내의 윈도우 슬라이드에 담긴 물건들을 "할인해서 구매한 물건들" 로 정의하였다. 

1. 주어진 배열 오름차순 정렬
2. 먼저 할인 가능하면 가능한 만큼 일단 구매한다.
3. 더 이상 할인 할 수 없으면 left 에 위치한 물건을 정가로 구매한다.,, left++
4. 애초에 할인 변수 a == 0 이면, 예외처리 해준다.
5. right 만큼 구매한 것임으로 right를 출력한다. 

문제의 요점은 "최대한 많은 물건을 구입하자 " 임으로 우선 할인 가능한 만큼 구매해주고 , 윈도우 슬라이드 범위를 유지하면서 물건을 구매 해주면 OK ! 

 

참고

자바에서는 누적합으로 비교하면 int형이 아닌 long형으로 해주어야 한다. 따라서 누적합을 계산하는 대신 현재 남은 예산 에서 다음 번쨰 구매할 가격 만큼 뺄셈을 해 주었다. 

if(right - left < a){
                    b-=nums[right]/2;//할인된가격 산다.
                    if(b < 0) break;
                    right++;
                }else{
                    if(a >0)b-=nums[left++]/2;
                    else {
                        b-= nums[right];
                        if(b < 0)break;
                        right++;
                    }
                }

처음에 같은 로직인데 정수를 리턴하는 코드가 아닌 System.out.println(ans) 하는 식으로 했는데 출력 초과가 났다... 답답해서 그냥 다시 짰다. 

 

코드

자바

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

public class Main {
    int n, b, a;
    int nums[];
    public static void main(String args[]) throws IOException {
        Main m = new Main();
        m.sol();

    }
    public int getN(){
        boolean temp = true;
        int right =0;
        int left =0;
        for(int i = 0 ;i < a ; i++){
            b-=nums[i]/2;
            right = i+1;
            if(b < 0){
                temp = false;
                return i;
            }
        }
        if(temp){
            while(right < n){

                if(right - left < a){
                    b-=nums[right]/2;//할인된가격 산다.
                    if(b < 0) break;
                    right++;
                }else{
                    if(a >0)b-=nums[left++]/2;
                    else {
                        b-= nums[right];
                        if(b < 0)break;
                        right++;
                    }
                }
            }
            return right;
        }
        return right;
    }
    public void sol() throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String q = br.readLine();
        n= Integer.parseInt(q.split(" ")[0]);
        b= Integer.parseInt(q.split(" ")[1]);
        a = Integer.parseInt(q.split(" ")[2]);//최대 선물의 수d
        nums = new int[n];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i =0; i< n;i++) {
            nums[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(nums);
        System.out.println(getN());
    }


}

파이썬

class Main():

    def __init__(self):
        n, b, a = map(int, input().split())
        nums = list(map(int, input().split()))
        nums.sort()
        print(self.getN(n,b,a,nums))

    def getN(self,n,b,a,nums):
        right =0 
        left =0 
        for i in range(a):#할인가능한만큼 산다. 
            b-=nums[i]//2
            right = i+1
            if b < 0 : return i
        
        while right < n:
            if right - left < a: #슬라이딩 개수 < 할인 개수
                b-= nums[right]//2
                if b < 0 : break
                right +=1
            else:       # 슬라이딩 개수 >= 할인 개수
                if a > 0 : 
                    b-=nums[left]//2 #nums[left]는 정가로 산다.
                    left+=1
                else: #예외 처리
                    b-=nums[right]
                    if b < 0 : break
                    right +=1 
        return right

a = Main()

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

[Java/Python] 백준 11501 주식  (0) 2023.01.19
[Java] 백준 1700번 멀티탭 스케줄링  (0) 2023.01.19
[Java] 백준 2517 달리기  (0) 2023.01.15
[Java] 백준 15975. 화살표 그리기  (0) 2023.01.13
[java] 백준 2212 센서  (2) 2023.01.08
Comments