728x90
⬛ 03. 자료 구조
⬛ 03-2. 구간 합
- S[i] = S[i-1] + A[i]
- i ~ j까지의 구간 합 구하기 : S[j] - S[i-1]
🟦 백준 11659번. 구간 합 구하기
- S[i] 는 1~i까지의 합 : 먼저 구해놓고,
- M개의 입력받은 구간 a,b 사잇 구간합을 구해서 출력
import java.util.ArrayList;
import java.util.Scanner;
//11659번. 구간 합 구하기 4
public class Main {
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt();
int M = kb.nextInt();
int[] A = new int[N+1];
int[] S = new int[N+1];
for(int i=1; i<=N; i++) {
A[i] = kb.nextInt();
}
S[1] = A[1];
for(int i=2; i<=N; i++) {
S[i] = S[i-1] + A[i];// 구간 합 구해두고
}
ArrayList<Integer > answer = new ArrayList<>();
for(int i=0; i<M; i++) {
int a = kb.nextInt();
int b = kb.nextInt();
answer.add(S[b] - S[a-1]);
}
//정답 출력
for(int x : answer ) System.out.println(x);
}
}
🟦 백준 11660번. 구간 합 구하기 2
- 점화식 정의도 해야 한다.
1) DP[X][Y] = 0,0 ~ x,y 까지의 구간 합을 미리 구해두는 것
2) 1행과 1열에 대한 초기화 필요
D[i][1] = D[i-1][1] + A[i][1];
//즉, 1행 쪽은 (왼쪽값 + 현재값)
D[1][j] = D[1][j-1] + A[1][j];
//즉, 1열 쪽은 (윗쪽값 + 현재값)
3) 이제 D[i][j] 의 값을 채우는 구간 합 공식 필요
왼쪽값 + 위쪽값 - (왼쪽대각선 겹치는 부분 제외) + 현재값
D[i][j] = D[i-1][j] + D[i][j-1] + D[i-1][j-1] + A[i][j];
4) 질의 구간합 구하는 공식 필요
(X1, Y1) (X2, Y2) 들어오면
D[X2][Y2] - D[X1-1][Y2] - D[X2][Y2-1] + D[x1-1][y1-1]
코드
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt();
int M = kb.nextInt();
int[][] A = new int[N+1][N+1];
//입력 데이터 세팅
for(int i=1; i<=N; i++) {
for(int j=1; j<=N; j++) {
A[i][j] = kb.nextInt();
}
}
//구간 합 구해놓기 1행 1열 초기화
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-1][j] + D[i][j-1] - D[i-1][j-1] + A[i][j];
}
}
//이제 각 구간별 질의 대답 정하기
ArrayList<Integer> answer = new ArrayList<>();
for(int i=0; i<M; i++) {
int x1 = kb.nextInt();
int y1 = kb.nextInt();
int x2 = kb.nextInt();
int y2 = kb.nextInt();
int tmp = D[x2][y2] - D[x1-1][y2] - D[x2][y1-1] + D[x1-1][y1-1];
answer.add(tmp);
}
//정답 출력
for(int x : answer) System.out.println(x);
}
}
⬛ 03-3. 투 포인터
- while(i<j) 문 돌면서, 찾고자 하는 값 타나나기 전까지 i와 j를 움직이는 방식
🟦 백준 2018번. 연속된 자연수 합 구하기
- [주의] 여기서 cnt=1로 초기화 하는 이유 : 15 자기 자신을 뽑는 1가지 경우를 미리 세팅한 것.
import java.util.Scanner;
/*2018번 수들의 합 */
public class Main {
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt();
int st =1, ed =1;
int sum =1;
int cnt = 1;
while(ed != N) {
if(sum == N) {
cnt++;
ed++;
sum += ed;
}else if(sum <N) {
ed++;
sum += ed;
}else if(sum > N) {
sum -= st;
st++;
}
}
System.out.println(cnt);
}
}
🟦 백준 1940번. 주몽의 명령
import java.util.Arrays;
import java.util.Scanner;
/*1940번. 주몽의 명령 */
public class Main {
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt(); //재료개수
int M = kb.nextInt(); //타겟값
int[] A = new int[N];
for(int i=0; i<N; i++) {
A[i] = kb.nextInt();
}
//1) 정렬 시킴 오름차순
Arrays.sort(A);
//2) 왼, 오 포인터로 찍으면서 답찾기
int cnt = 0;
int st = 0, ed = N-1;
int sum = 0;
while(st<ed) {
sum = A[st] + A[ed];//두 재료의 합
if(sum == M) { //정답 찾으면
cnt++;
st++;
ed--;
}else if(sum < M) { //값이 작으면
st++;
}else if(sum > M) { //값이 더 크면
ed--;
}
}
System.out.println(cnt);//출력
}
}
🟦 백준 1253번. 좋은 수 구하기
package to_0717_5;
import java.util.Arrays;
import java.util.Scanner;
/*1253번. 좋은 수 구하기 */
public class Main {
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt();
long[] A = new long[N];
for(int i=0; i<N; i++) A[i] = kb.nextLong();
Arrays.sort(A);//오름차순 정렬 시켜놓고
int cnt=0;
for(int k=0; k<N; k++) {
long find = A[k];
int st = 0;
int ed = N-1;
while(st < ed) {
if(A[st] + A[ed] == find) {
if(st != k && ed !=k ) {
cnt++;
break;
}else if(st == k) { //자기 자신 제외
st++;
}else {//자기 자신 제외
ed--;
}
}else if(A[st]+A[ed] < find) {
st++;
}else {
ed--;
}
}
}
//정답 출력
System.out.println(cnt);
}
}
⬛ 03-5. 스택과 큐
- 스택 : 후입선출
- 큐 : 선입선출
🟦 백준 2164번. 카드 게임
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/*2164번. 카드2 */
public class Main {
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner kb= new Scanner(System.in);
int N = kb.nextInt();
Queue<Integer> Q = new LinkedList<>();
//값 넣기
for(int i=1; i<=N; i++) Q.add(i);
while(Q.size() > 1) {
//1) 첫장은 버리기
Q.poll();
//2) 그 다음 장은 맨 뒤에 담기
Q.add(Q.poll());
}
if(Q.size() == 1) {
int tmp = Q.poll();
System.out.println(tmp);//가장 마지막에 남은 카드 출력
}
}
}
728x90
'알고리즘 이론 [개념] > [복습] 코테_알고리즘 복습' 카테고리의 다른 글
알고리즘 및 코테 복습 - DP 동적 계획법 (0) | 2023.07.25 |
---|---|
알고리즘 및 코테 복습 - 그래프(Graph) (0) | 2023.07.24 |
알고리즘 및 코테 복습 - 그리디 (Greedy) (0) | 2023.07.18 |
알고리즘 및 코테 복습 - DFS, BFS, 이진 탐색 (0) | 2023.07.17 |