티스토리 뷰
https://www.acmicpc.net/problem/5710

문제
최근에 전기 회사는 전기 요금을 또 올렸다. 새로운 전기 요금은 아래 표에 나와있다. (사용량은 항상 양의 정수)
사용량 (Watt-hour)요금 (원)
| 1 ~ 100 | 2 |
| 101 ~ 10000 | 3 |
| 10001 ~ 1000000 | 5 |
| > 1000000 | 7 |
위의 표를 읽는 방법은 다음과 같다.
사용량의 첫 100Wh의 가격은 1Wh당 2원이다. 다음 9900Wh (101 ~ 10000)의 가격은 1Wh당 3원이다. 이런식으로 계속 계산한다.
예를 들어, 10123Wh를 사용했을 때, 내야하는 요금은 2×100 + 3×9900 + 5×123 = 30515원이다.
전기 회사는 전기 요금을 인상하지 않고 돈을 더 버는 이상한 방법을 만들었다. 그 방법은 바로 사용한 전기의 양을 알려주지 않고, 얼마를 내야 하는지 알려주는 것이다. 전기 회사는 요금과 관련된 정보를 나타내는 두 숫자 A와 B를 알려준다. A와 B는 전기 회사에서 그 사람이 사는 건물에서 임의로 고른 이웃의 정보와 합친 요금이다.
- A: 이웃의 사용량과 사용량을 합쳤을 때 내야하는 요금
- B: 이웃의 전기 요금과의 차이 (절댓값)
위의 두 숫자를 이용해서 자신이 얼마를 내야 하는지를 계산할 수 없을 때는, 계산 요금을 100원을 더 내면 전기 회사에서 사용량을 알려준다.
상근이는 매우 전기를 아끼는 사람이다. 따라서, 항상 자신이 사는 건물에서 가장 전기를 적게 쓴다고 확신한다. 상근이는 돈도 전기만큼 아낀다. 따라서, 절대로 계산 요금을 지불하지 않고 자신이 직접 계산할 것이다.
예를 들어, A = 1100, B = 300이라고 하자. 이 정보를 이용하면, 상근이의 사용량은 150Wh, 이웃의 사용량은 250Wh임을 알 수 있다. 두 사람의 총 사용량은 400Wh이다. 따라서, A = 2×100 + 3×300 = 1100이 된다. 따라서, 상근이는 350원을 내면 된다. 상근이의 이웃은 2×100 + 3×150 = 650원을 내야 하고, B = |350 - 650| = 300이 된다.
A와 B가 주어졌을 때, 상근이가 내야하는 전기 요금을 구하는 프로그램을 작성하시오.
유형 : 이진 탐색
접근 방식
- 우선 A가 의미하는 것은 상근이와 이웃의 총 사용량을 합쳤을 때의 전기 요금이다.
- 해당 값을 표에 대해 역으로 계산하면 (상근이와 이웃의 전기 총 사용량)을 구할 수 있다.
- 문제에서 가장 큰 힌트가 주어졌다. 바로 '항상 자신이 사는 건물에서 가장 전기를 적게 쓴다고 확신'이라는 것이다.
- 이 문장이 의미하는 것은 상근이의 전기 사용량은 절대 (총 사용량 / 2)를 넘지 않는다는 것이다.
- 즉 이진 탐색 시 l = 0, r = total / 2 이라는 것이다.
- 또한 이진 탐색 시 상근이와 이웃의 사용량의 차이가 구해질 것이다.
- 이 값이 B보다 작다는 것은 상근이의 사용량이 너무 많다는 것이다.
- 반대로 B보다 크다는 것은 상근이의 사용량이 너무 적다는 것이다.
전체 코드
import java.util.*;
import java.io.*;
public class Main {
static int A,B;
static long totalUse = 0;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
while(true){
st = new StringTokenizer(br.readLine()," ");
A = Integer.parseInt(st.nextToken());
B = Integer.parseInt(st.nextToken());
if(A == 0 && B == 0)
break;
totalUse = calTotal();
long tmp = bs(totalUse);
sb.append(tmp+"\n");
}
System.out.print(sb.toString());
br.close();
}
static long bs(long tmp) {
long l = 0;
long r = tmp / 2;
long mid = 0;
while(l <= r) {
mid = (l + r) / 2;
long sang = cal(mid);
long neighbor = cal(tmp - mid);
if(Math.abs(sang - neighbor) == B){
return sang;
}
if(Math.abs(sang - neighbor) > B) {
l = mid + 1;
}else {
r = mid - 1;
}
}
return 0;
}
static long cal(long use) {
if(use >= 1 && use <= 100) {
return 2 * use;
}else if(use >= 101 && use <= 10000) {
return 200 + 3 *(use - 100);
}else if(use >= 10001 && use <= 1000000) {
return 200 + (9900 * 3) + 5 *(use - 10000);
}else if(use > 1000000) {
return 200 + (9900 * 3) + (5 * 990000) + (7 * (use - 1000000));
}
return 0;
}
static long calTotal() {
long tmpA = A;
long result = 0;
if(tmpA <= 200) {
return tmpA / 2;
}else{
result += 100;
tmpA -= 200;
if(tmpA <= (9900 * 3)) {
result += tmpA / 3;
return result;
}else {
result += 9900;
tmpA -= (9900 * 3);
if(tmpA <= (990000 * 5)) {
result += tmpA / 5;
return result;
}else {
result += 990000;
tmpA -= (990000 * 5);
result += tmpA / 7;
return result;
}
}
}
}
}'알고리즘 > 백준' 카테고리의 다른 글
| 백준 30024 (옥수수밭) - java (0) | 2024.06.20 |
|---|---|
| 백준 4148 (31게임) - java (1) | 2024.06.17 |
| 백준 19640 (화장실의 규칙) - java (1) | 2024.06.02 |
| 백준 13168 (내일로 여행) - java (0) | 2024.06.02 |
| 백준 22254 (공정 컨설턴트 호석) - java (0) | 2024.05.30 |
- Total
- Today
- Yesterday
- 백준 #치즈 #2638
- 백준 #2636 #치즈
- 백준 #
- 백준 #12014 #주식 #자바 #java
- 백준 #17940 #주식 #자바 #java
- 백준 #1759 #암호 만들기
- 백준 #4963 #섬의 개수
- 백준 #14863 #서울에서 경산까지 #java #자바
- 백준 #인구 이동 #16234
- 백준 #2580 #스도쿠
- 백준 #15686 #치킨 배달
- 올해보다
- 백준 #13549 #숨바꼭질3
- 17394
- 백준 #18405 #경쟁적 전염
- 백준 #5721 #사탕 줍기 대회 #java #자바
- 17218
- 백준 #1987 #알파벳 #자바 #java
- 백준 #25603 #짱해커 이동식 #java #자바
- 자바 #JAVA
- 행복합시다.
- 백준 #16973 #직사각형 탈출
- 백준 #1325 #효율적인 해킹
- 백준 #3980 #선발 명단
- 백준 #1584 #게임 #java #자바
- 백준 #다리 만들기 #2146
- 자바
- 백준
- Java
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |