티스토리 뷰
https://www.acmicpc.net/problem/2632
2632번: 피자판매
첫 번째 줄에는 손님이 구매하고자 하는 피자크기를 나타내는 2,000,000 이하의 자연수가 주어진다. 두 번째 줄에는 A, B 피자의 피자조각의 개수를 나타내 는 정수 m, n 이 차례로 주어진다 (3 ≤ m, n
www.acmicpc.net

문제
고객이 두 종류의 피자 A와 B를 취급하는 피자가게에서 피자를 주문하고자 한다. <그림 1>과 같이 각 종류의 피자는 다양한 크기의 여러 개의 피자조각으로 나누어져 있다. 각 조각에 쓰여진 숫자는 피자조각의 크기를 나타낸다.

고객이 원하는 피자의 크기를 이야기하면, 피자가게에서는 한 종류의 피자를 2 조각 이상 판매할 때는 반드시 연속된 조각들을 잘라서 판매한다. 이때 판매한 피자조각의 크기 합이 주문한 크기가 되어야 한다. 판매한 피자조각은 모두 A종류이거나, 모두 B종류이거나, 또는 A와 B 종류가 혼합될 수 있다. 예를 들어서, <그림 1> 과 같이 잘라진 피자가 있을 때, 손님이 전체 크기가 7 인 피자를 주문하면, 피자 가게에서는 <그림2>와 같이 5 가지 방법으로 피자를 판매할 수 있다.

피자가게에서 손님이 원하는 크기의 피자를 판매하는 모든 방법의 가지 수를 계산하는 프로그램을 작성하시오
유형 : 누적합
접근 방식
- 각 피자를 배열로 봤을 때 중요한 점은 원형 형태라는 것이다.
- 우선 각 배열의 누적합 배열을 구한다.
- 그리고 각 지점을 기준으로 끝까지 한 방향으로 진행할 때의 구간 값들의 숫자를 count 배열에 추가한다.
- 문제의 핵심은 역순 연산이다. 원형으로 이어져 있을 때 누적합을 구하는 방법은 간단하다.
- i 지점을 기준으로 첫번 째 원소부터 i 지점의 누적합에 (마지막 인덱스 부터 i + 1 인덱스 지점까지의 구간합니다.)
- 즉 A[i] + A[n] - A[j] ( j 는 n-1 부터 i + 1 까지 )

전체 코드
import java.util.*;
import java.io.*;
public class BOJ_2632_피자판매 {
static int des,n,m;
static int[] A;
static int[] B;
static int[] aCount = new int[2_000_001];
static int[] bCount = new int[2_000_001];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
des = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine()," ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
A = new int[n+1];
B = new int[m+1];
for(int i = 1 ; i <= n ; i++){
int cur = Integer.parseInt(br.readLine());
A[i] = A[i-1] + cur;
}
for(int j = 1 ; j <= m ; j++){
int cur = Integer.parseInt(br.readLine());
B[j] = B[j-1] + cur;
}
for(int i = 1 ; i <= n ; i++){
for(int j = i ; j <= n ; j++){
int tmpSum = A[j] - A[i-1];
aCount[tmpSum]++;
}
}
for(int i = 1 ; i <= m ; i++){
for(int j = i; j <= m ; j++){
int tmpSum = B[j] - B[i-1];
bCount[tmpSum]++;
}
}
for(int i = 1 ; i <= n ; i++){
for(int j = n - 1 ; j >= i + 1; j--){
int tmpSum = A[i] + A[n] - A[j];
aCount[tmpSum]++;
}
}
for(int i = 1 ; i <= m ; i++){
for(int j = m - 1 ; j >= i + 1 ; j--){
int tmpSum = B[i] + B[m] - B[j];
bCount[tmpSum]++;
}
}
long result = 0;
if(des <= 1000_000){
result += aCount[des] + bCount[des];
}
for(int i = 1 ; i < des ; i++){
if(i > 1000_000 || (des - i) > 1000_000)
continue;
result += (aCount[i] * bCount[des - i]);
}
System.out.println(result);
br.close();
}
}
'알고리즘 > 백준' 카테고리의 다른 글
| 백준 24391 (귀찮은 해강이) - java (0) | 2024.04.23 |
|---|---|
| 백준 16118 (달빛 여우) java (1) | 2024.04.21 |
| 백준 17143 (낚시왕) - java (0) | 2024.04.02 |
| 백준 18224 (미로에 갇힌 건우) - java (0) | 2024.03.31 |
| 백준 12763 (지각하면 안 돼) - java (0) | 2024.03.27 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준 #
- 백준 #15686 #치킨 배달
- 행복합시다.
- 백준 #17940 #주식 #자바 #java
- 백준 #다리 만들기 #2146
- 백준 #16973 #직사각형 탈출
- 백준 #1584 #게임 #java #자바
- 백준 #1759 #암호 만들기
- 백준 #18405 #경쟁적 전염
- 백준 #4963 #섬의 개수
- 올해보다
- 백준 #1325 #효율적인 해킹
- 자바 #JAVA
- 백준 #2580 #스도쿠
- 백준
- 17218
- 백준 #14863 #서울에서 경산까지 #java #자바
- 백준 #1987 #알파벳 #자바 #java
- 17394
- 백준 #25603 #짱해커 이동식 #java #자바
- 자바
- 백준 #5721 #사탕 줍기 대회 #java #자바
- Java
- 백준 #12014 #주식 #자바 #java
- 백준 #13549 #숨바꼭질3
- 백준 #치즈 #2638
- 백준 #인구 이동 #16234
- 백준 #2636 #치즈
- 백준 #28140 #빨강~ 빨강~ 파랑! 파랑! 달콤한 솜사탕! #java #자바
- 백준 #3980 #선발 명단
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
글 보관함