[백준] 1300번 - K번째 수 (C언어) [Gold2]

2023. 6. 6. 17:24·알고리즘
더보기
input output
3
7
6

해당 문제는 단순히 이중 배열을 선언하여 정렬하려고 한다면 시간 초과가 발생할 것이다. 따라서  빠르게 해결할 수 있는 알고리즘인 이진 탐색(이분 탐색)을 사용하였다. 

 

기본적인 알고리즘은 아래와 같다.

더보기

low=1, high=n*n으로 설정


low <= high 일 동안 while문 루프
mid값 구하기
mid값보다 작거나 같은 수들 구하기 => cnt

cnt값이 목표 인덱스 보다 크거나 같을 경우
mid를 왼쪽으로 옮기기

cnt값이 목표 인덱스 보다 작을 경우
mid를 오른쪽으로 옮기기


루프 탈출 후 low값 출력

 

[n = 3 , k = 5 인 경우]

array[3][3] 1 2 3
1 1 2 3
2 2 4 6
3 3 6 9

*mid 값보다 작은 값들의 갯수를 구하는 함수 먼저 구현

ll func(ll x) { // mid보다 작은 수들의 개수를 시간 초과 없이 시간 복잡도 O(n) 으로 구현
	ll sum = 0;

	for (int i = 1; i <= n; i++){ 
		sum += min(x / i, n);
	}
	return sum;
}

mid = 5 

함수 결과 : 2 + 2 + 1 = 5

k 1 2 3 4 5 6 7 8 9
array[k] 1 2 3 2 4 6 3 6 9

mid 값보다 작은 값들의 갯수 : 5개

 

알고리즘을 이용하여 코드를 작성하면 전체 소스 코드는 아래와 같다.

/*
	low=1, high=n*n으로 설정
		low <= high 일 동안 while문 루프
			mid값 구하기
		mid값보다 작거나 같은 수들 구하기 => cnt
		
		cnt값이 목표 인덱스(K) 보다 크거나 같을 경우
		mid를 좀 더 왼쪽으로 옮겨야 한다.
		high = mid - 1
	
		cnt값이 목표 인덱스(K) 보다 작을 경우
		mid를 좀 더 오른쪽으로 옮겨야 한다.
		low = mid + 1
	루프 탈출 후 low값 출력
*/
#include <stdio.h>
#define min(a,b) (a) < (b) ? (a) : (b)
#pragma warning(disable:4996)
#define INF 1000000000
typedef long long int ll;
ll n, k;
ll low, high, mid;
ll cnt;

ll func(ll x) { // mid보다 작은 수들의 개수를 시간 초과 없이 시간 복잡도 O(n) 으로 구현
	ll sum = 0;

	for (int i = 1; i <= n; i++){ 
		sum += min(x / i, n);
	}
	return sum;
}

int main() {
	scanf("%lld%lld", &n, &k);

	low = 1;
	high = n * n;

	k = min((long long)INF, k);

	while (low <= high) { // 이진 탐색
		mid = (low + high) / 2;

		cnt = func(mid); 

		if (cnt >= k) { // cnt값이 목표 인덱스 보다 크거나 같을 경우
			high = mid - 1; // high 값 업데이트
		}
		else { // cnt값이 목표 인덱스 보다 작을 경우 
			low = mid + 1; // low 값 업데이트
		}
	}
	
	printf("%d", low); // 루프 탈출 후 low 값 출력

	return 0;
}

이진 탐색의 개념과 시간 복잡도를 줄일 수 있는 방법을 안다면 쉽게 해결 가능한 문제였다.

 

[1300번]

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

 

1300번: K번째 수

세준이는 크기가 N×N인 배열 A를 만들었다. 배열에 들어있는 수 A[i][j] = i×j 이다. 이 수를 일차원 배열 B에 넣으면 B의 크기는 N×N이 된다. B를 오름차순 정렬했을 때, B[k]를 구해보자. 배열 A와 B

www.acmicpc.net

 

[github]

https://github.com/MinWook6457

 

MinWook6457 - Overview

MinWook6457 has 18 repositories available. Follow their code on GitHub.

github.com

 

 

'알고리즘' 카테고리의 다른 글

[경시대회] 왜 아픈 상처에 소금을 뿌리십니까?  (0) 2024.05.08
[경시대회] 소믈리에 구름이  (0) 2024.05.08
[백준] 11053번 - 가장 긴 증가하는 부분 수열 (C언어) [Silver2]  (0) 2023.06.02
[백준] 1517번 - 버블 소트 (C언어) [Platinum5]  (0) 2023.06.01
[백준] 2042번 - 구간 합 구하기 (C언어) [Gold1]  (0) 2023.05.31
'알고리즘' 카테고리의 다른 글
  • [경시대회] 왜 아픈 상처에 소금을 뿌리십니까?
  • [경시대회] 소믈리에 구름이
  • [백준] 11053번 - 가장 긴 증가하는 부분 수열 (C언어) [Silver2]
  • [백준] 1517번 - 버블 소트 (C언어) [Platinum5]
min._.uuk_
min._.uuk_
하루 하나 기록하기
  • min._.uuk_
    기록하는 습관
    min._.uuk_
  • 전체
    오늘
    어제
    • 분류 전체보기 (33)
      • 알고리즘 (15)
      • 자바 스크립트 (2)
      • 인실리코젠 (15)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    백준 #BOJ #스택 #수열
    JS #테트리스 #HTML #CSS #추억의 게임
    Apache #POI #JAVA #maven
    백준 #MST #최소비용신장트리 #크루스칼 #그리디 #알고리즘
    인실리코젠 #크롤링 #SpringBoot #MVC #jQuery
    백준 #세그먼트 트리 #구간합 #c언어 #골드1 #탐색
    백준 #후위표기식 #스택 #중위표기식 #우선순위 #1918번
    백준 #동적계획법 #dp #백트래킹 #dfs
    백준 #1407번 #재귀함수
    #BOJ #백준 #10989번 #C언어 #카운팅정렬 #정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
min._.uuk_
[백준] 1300번 - K번째 수 (C언어) [Gold2]
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.