Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
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
29 30
Archives
Today
Total
관리 메뉴

hwooo

BOJ (C/C++) 1024번: 수열의 합 본문

Study/Algorithm

BOJ (C/C++) 1024번: 수열의 합

hwooo 2022. 11. 3. 03:21

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

 

1024번: 수열의 합

첫째 줄에 N과 L이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이고, L은 2보다 크거나 같고, 100보다 작거나 같은 자연수이다.

www.acmicpc.net


풀이

L개의 정수를 더해 N이 되어야 하므로 그 수들은 N/L 부근에 있다. 따라서 mid=N/L로 두고 L이 짝수/홀수일 때 리스트가 달라지므로 그 경우로 나눴다. 이 때 시작 지점(s)과 끝 지점(e)을 구해 에러 조건 판별( -1 출력)과 출력에 사용했다.
(에러 검증은 반복문 안에서 수행해야 시간초과가 나지 않는다)
또한 L이 짝수일 경우 3 4 5 6 7 8 처럼 가운데 두 수의 합과 mid-n, (mid+1)+n의 합은 동일하고,
홀수일 경우 1 2 3 4 5 처럼 가운데 수의 2배가 mid-1, mid+1의 합과 동일하므로 이를 이용해 수열의 합을 구했다.
(반복문으로 실행 시 시간초과)

 

또한 5 6 7, 6 7 8 처럼 한 자리씩 차이나는 수를 sum_m, sum_M으로 정하여 N이 이 사이의 값일 경우 L을 증가시켜줬다.N이 작은 합보다 작으면 수열의 위치를 1씩 증가, N이 큰 합보다 크면 수열의 위치를 1씩 감소시켜 N에 가까워지게 함.

코드

#include <stdio.h>
int main() {
	int N, L;
	int mid, s, e, sum_m, sum_M;
	bool change = true;

	scanf("%d %d", &N, &L);
	while (1) {

		// L 변화 있을 때만
		if (change) {
			mid = N / L;
			if (L % 2) s = mid - L / 2, e = mid + L / 2;
			else s = mid - L / 2 + 1, e = mid + L / 2;

			if (L % 2) sum_m = mid + (2 * mid)*(L / 2);
			else sum_m = (2 * mid + 1)*(L / 2);

			sum_M = sum_m - s + (e + 1);

			change = false;
		}

		//error
		if (s < 0 || e - s + 1>100) {
			printf("-1");
			return 0;
		}

		if (sum_m == N) break;
		else if (sum_M == N) {
			s++, e++;
			break;
		}

		if (sum_m < N&&N < sum_M) L++, change = true;
		else if (N < sum_m) sum_M = sum_m, sum_m = sum_m - e + (s - 1);
		else if (N > sum_M) sum_m = sum_M, sum_M = sum_M + (e + 2) - (s + 1);
	}
	//print
	for (int i = s; i <= e; i++) printf("%d ", i);

	return 0;
}

'Study > Algorithm' 카테고리의 다른 글

BOJ (C/C++) 1015번: 수열 정렬  (0) 2022.11.05
BOJ (C/C++) 1051번: 숫자 정사각형  (0) 2022.11.04
BOJ (C/C++) 1094번: 막대기  (0) 2022.11.02
BOJ (C/C++) 1058번: 친구  (0) 2022.11.01
BOJ (C/C++) 1049번: 기타줄  (0) 2022.11.01