하루에 3문제는 무리였나보다 ^-^..
004 숫자의 합 구하기(백준11660)
https://www.acmicpc.net/problem/11660
원래 숫자 리스트 A[i][j] 에서 배열에 대한 합 배열을 D[i][j] 인 배열을 만들어야한다.
합배열 공식
D[i][j] = D[i][j -1] + D[i -1][j] - D[i -1][j-1] + A[i][j]
예)
(1,2) 일 때, (1,1) (1,2) 을 더한 값이 합 배열에 들어간다.
합 배열 (1,4) 은 합 배열 (1,3) 과 리스트 배열의 (1,4) 합
합 배열 (3,4) 을 출력할려고 할 때,
합 배열 (2,4) + (3,3) 의 합 을 하고 중복 값 제거를 위해 - 리스트 배열(2,3) 제거 와 + 리스트 (3,4) 의 합이다.
질의에 대한 답을 도출하기 위한 과정
구간 합 배열을 이용하기 전에 질의에 대한 답을 도출하기 위한 과정을 만들어야한다.
질의에서 2234 면
(2,2) (3,4) 으로 인식하고
그러면, (3,1) (1,4) 부분을 빼주고 중복해서 빼준 값 (1,1) 값을 더해주면 된다.
질의 x1 y1 x2 y2 일때
D[x2][y2] - D[1][y2] - D[x2][1] + D[1][1]
코드 작성할 때,
n(리스트 크기) , m(질의 수)
A(원본 리스트), D(합 배열)
for n만큼 반복: 원본 리스트 데이터 저장
for i를 1부터 n까지 반복:
합 배열 저장
D[i][j] = D[i][j -1] + D[i -1][j] - D[i -1][j-1] + A[i][j]
for m만큼 반복 :
질의 대한 결과 계산 및 출력
D[x2][y2] - D[1][y2] - D[x2][1] + D[1][1]
코드 작성하기
package test.Num1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 문제4 {
public static void main(String[] args) throws IOException {
//bufferReader로 받기
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//받은 br 인스턴스를 String token으로 변환
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
//인덱스 0 부터 시작하는 걸 생각해서 만약 n = 3일 때, 4x4 값이 나오겠지?
int A[][] = new int[n+1][n+1];
//for 문을 이용하여 nxn 값 넣기
for(int i=1; i<=n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= n; j++) {
A[i][j] = Integer.parseInt(st.nextToken());
}
}
//합배열 저장
int D[][] = new int[n+1][n+1];
for (int i = 1; i<=n; i++) {
//구간의 합 구하기
for (int j = 1; j <= n; j++) {
D[i][j] = D[i][j - 1] + D[i - 1][j] - D[i - 1][j - 1] + A[i][j];
}
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int x1 = Integer.parseInt(st.nextToken());
int y1 = Integer.parseInt(st.nextToken());
int x2 = Integer.parseInt(st.nextToken());
int y2 = Integer.parseInt(st.nextToken());
int result = D[x2][y2] - D[x1 - 1][y2] - D[x2][y1 - 1]+ D[x1 - 1][y1 -1];
System.out.println(result);
}
}
}
005숫자의 합 구하기(백준10986)
N개의 A1,A2,.. An 이 주어졌을 때 연속된 부분의 합이 M으로 나누어떨어지는 구간의 개수
연속된 부분의 합이 M으로 나누어 떨어진다.
N 은 수의 개수 M 은 3으로 나누어 떨어지는 구간
1,2,3,1,2 라고 했을 때, (1,2) (1,2,3) (1,2,3,1,2),(2,3,1)(3),(3,1,2),(1,2) 이 나온다
나머지를 계산할 때, ((1%3) + (2%3))% 3 은 (1+2)%3 와 동일하다.
우선 배열로 넣어보면, 일반 값이 들어있는
리스트A:
1 | 2 | 3 | 1 | 2 |
합 배열 S:
1 | 3 | 6 | 7 | 9 |
합 배열에 대한 %3 나머지 배열 :
1 | 0 | 0 | 1 | 0 |
나머지 배열에서 0이라고 되어 있는 애들은 바로 M 인 3을 나눠주면 0 이기 때문에 "경우의 수" 에 더해준다.
0의 나머지를 가진 애들은 3개
나머지가 나오는 애들은 2개
나머지가 0으로 떨어지는 수 = 3개
이제, 집중해서 봐야할 부분... ㅠ
구간을 선택할 때,
나머지 배열에 이루어진 애들을 M으로 나누면 무조건 나머지는 0 이 나오는데,
예) 나머지배열 (s[4] - s[2] ) % 3 = 0
같은 나머지를 애들은 가지고 만든 구간의 합은 나머지가 0이 나온다.
총 나머지가 0 인 애들이 3개 이기 때문에 구간을 선택해야 하기 때문에 2개를 선택해야한다.
3개중에 2개 선택할 경우의 수 3C2 = 3C1 = 3개
1 은 2개가 있는데 그 중 2개를 선택해야하기 때문에, 2C2 로 식이 나온다. 즉, 경우의 수를 알아 낸다. = 1개
는 총 7개 나온다.
슈도코드 작성하기
n 입력받기(수열의 개수)
m 입력받기(나누어떨어져야 하는 수)
A 입력받기(원본 수열 저장 리스트)
S 입력받기(합 배열)
C 입력받기(같은 나머지 인덱스를 카운트하는 리스트)
answer 선언하기 (정답 변수)
#합배열 저장 '배열의 합' 저장이기 때문에 1부터 시작한다
for i -> 1 ~ n-1
S[i] = S[i-1] + A[i]
#합배열을 나눈 나머지 값 0번째 배열부터 나누기 때문에 0부터 시작한다.
for i -> 0 ~ n-1
rem = S[i] % M
if(rem == 0) :
answer =+1
#C[rem]의 값을 1개 증가
#C[i] (i가 나머지인 인덱스의 개수) 에서 2가지를 뽑는 경우의 수를 정답에 더하기
for i -> 0 ~ m-1 :
#C[i]개 중 2개를 뽑는 경우의 수 계산 공식 C[i] * (C[i]-1)/2
코드 작성하기
import sys
input = sys.stdin.readline
#split 사용하여 띄어쓰기 기준으로 나눠서 저장
# n 은 수열의 개수
n, m= map(int, input().split())
A = list(map(int, input().split()))
#0으로 초기화 하여 n 만큼 키울 것이다
S = [0] * n
# m은 나누어 떨어져야 하는 수
# C 은 같은 나머지의 들을 카운트하는 리스트
C = [0] * m
answer = 0
S[0] = A[0]
#처음에 0번째 값은 0으로 넣어주자
#1번 인덱스부터 시작하도록 하자
for i in range (1, n) :
S[i] = S[i-1] + A[i]
for i in range(n):
remin = S[i] % m
#만약에 나머지수가 0이 나올 경우 답의 경우 수 값을 1증가 시켜준다
if remin == 0 :
answer += 1
#remin 값을 인덱스로 넣고 그럼 배열의 인덱스는 0,1 밖에 안남을 것이다
#거기서 나머지가 1인 애들이 3개가 생길 경우 인덱스 1은 3이 나올 것이다.
C[remin] += 1
for i in range() :
#C배열에 있는 수가 1이상인 것은 나머지가 같은 것이 여러 개 라는 것
if C[i] > 1 :
answer += ( C[i]*(C[i]-1) //2 )
print(answer)
이전에 풀었지만, 파이썬 언어로 다시 풀어보고 싶어서 가져온 브론즈 문제
001 숫자의 합 구하기(백준11720)
바로 코드 작성하기
#숫자의 개수
n = input()
#공백없이 주어지는 n개의 숫자들로 배열을 만든다
m = list(input())
sum = 0
#n개의 인덱스 안에 m 의 숫자들을 넣었으니, 다 합하면 댐
for i in m :
sum = sum + int(i)
print(sum)
'코딩테스트' 카테고리의 다른 글
하루 코테 3개 풀기 - 6일차 (1) | 2024.12.16 |
---|---|
하루 코테 3개 풀기 - 5일차 (1) | 2024.12.14 |
하루 코테 3개 풀기 - 4일차 (0) | 2024.12.13 |
하루 코테 3문제풀기 - 3일차 (2) | 2024.12.13 |
하루 코테 3문제풀기-1일차 (1) | 2024.12.08 |