์ฝ”๋”ฉํ…Œ์ŠคํŠธ/์•Œ๊ณ ๋ฆฌ์ฆ˜

[C++ ์•Œ๊ณ ๋ฆฌ์ฆ˜] ๋ถ„ํ• ์ •๋ณต(Divide and conquer)

kite707 2021. 8. 28.

๊ฐœ๋…

๋ถ„ํ• ์ •๋ณต ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ฃผ์–ด์ง„ ๋ฌธ์ œ๋ฅผ ๋‘˜ ์ด์ƒ์˜ ๋ถ€๋ถ„๋ฌธ์ œ๋กœ ๋‚˜๋ˆˆ ๋’ค ๊ฐ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‹ต์„ ๊ณ„์‚ฐํ•˜๊ณ , ์ด๋ฅผ ๋ณ‘ํ•ฉํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ข…๋งŒ๋ถ์˜ ํ‘œํ˜„์„ ๋นŒ๋ฆฌ์ž๋ฉด ๊ฐ๊ฐœ ๊ฒฉํŒŒ ๋ผ๊ณ  ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ฐ”๋กœ ์˜ˆ์ œ๋ฅผ ๋ณด๋„๋ก ํ•˜์ž.

 

์˜ˆ์ œ 1 : ์ˆ˜์—ด์˜ ํ•ฉ

1๋ถ€ํ„ฐ N๊นŒ์ง€์˜ ๊ฐ’์„ ๊ตฌํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ์ด๋ฅผ ๋‹จ์ˆœ ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์„ ๊ฒƒ์ด๋‹ค.

#include <iostream>
using namespace std;

int recursiveSum(int N) {
	if (N == 1) {
		return N;
	}
	else {
		return recursiveSum(N - 1) + N;
	}
}

int main() {
	int A;
	cin >> A;
	cout << recursiveSum(A);
}

์žฌ๊ท€ํ•จ์ˆ˜๋กœ ํ•จ์ˆ˜๋ฅผ ์งœ๋ฉด ๊ต‰์žฅํžˆ ์ง๊ด€์ ์ด์ง€๋งŒ ์œ„ ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. ๋˜ 5000์ •๋„์˜ ์ˆซ์ž๋ถ€ํ„ฐ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์–ด๋ฒ„๋ฆฐ๋‹ค.

์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ์งœ๋ณด์ž. 1+2+3+4+...+N์ด๋ผ๋Š” ์‹์„ ์‚ด์ง ๋ณ€ํ˜•ํ•ด์„œ ๋ถ„ํ• ์ •๋ณต์„ ํ•˜๊ธฐ ์ข‹๊ฒŒ ๋ฐ”๊ฟ€ ๊ฒƒ์ด๋‹ค. ์•„๋ž˜ ์‹์„ ๋ณด๋„๋ก ํ•˜์ž.

1+2+3+4+5+6+7+8
=(1+2+3+4)+(5+6+7+8)
=(1+2+3+4)+4*4+(1+2+3+4)
=2*(1+2+3+4)+4^2

์ด์ œ ์œ„ ์‹์„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ผ๋ฐ˜ํ™” ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

1+2+3+4+...N
=(1+2+3+4+...+N/2)+{(N/2+1)+(N/2+2)+(N/2+3)+...+(N/2+N/2)}
=(1+2+3+4+...+N/2)+{(N/2)*(N-2)}+(1+2+3+4+...+N/2)
=2*(1+2+3+4+...+N/2)+(N/2)^2

๋ฌธ์ œ๋ฅผ ๋ณด๋ฉด 1+2+3+4+...N์„ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ 1+2+3+...+N/2๋กœ ๋ฐ”๋€Œ์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์ด ๋ถ„ํ• ์ •๋ณต์˜ ํ•ต์‹ฌ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด 1+2+3+...+N/2๋ฅผ ๋˜ ์ชผ๊ฐœ๋ฉด 1+2+3+...+N/4๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ๋‚˜์˜ค๊ณ , ๊ณ„์†ํ•ด์„œ ์ชผ๊ฐœ๋‚˜๊ฐ€๋ฉด ๋ฌธ์ œ๋ฅผ ์ ์  ์ž‘์€ ์กฐ๊ฐ์œผ๋กœ ์ž๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ๋ฌผ๋ก  ์œ„ ์‹์€ ์ง์ˆ˜์ผ ๊ฒฝ์šฐ๋งŒ ์ ์šฉ๋œ๋‹ค. ํ™€์ˆ˜์ผ ๊ฒฝ์šฐ์—๋Š” N-1๊นŒ์ง€์˜ ํ•ฉ์„ ๊ตฌํ•˜๊ณ  N์„ ๋”ํ•˜๋Š” ์‹์œผ๋กœ ์ˆ˜์—ด์˜ ํ•ฉ์„ ๊ตฌํ•œ๋‹ค.

 

์œ„ ๊ณผ์ •์„ ์ฝ”๋“œ๋กœ ์งœ๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

#include <iostream> 
using namespace std;

int fastsum(int x) {
	if (x == 1) {
		return x;
	}
	else {
		if (x % 2 == 0) {
			return fastsum(x / 2) * 2 + (x / 2)*(x/2);
		}
		else {
			return fastsum((x - 1) / 2) * 2 + ((x - 1) / 2)* ((x - 1) / 2) + x;
		}
	}
}

int main() {
	int A;
	cin >> A;
	cout << fastsum(A);
}

์ด์ œ ํฐ ์ˆ˜๋ฅผ ๋„ฃ์–ด๋„ ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰ ๋‘ ๋ฒˆ์งธ ์ฝ”๋“œ๊ฐ€ ๋” ํšจ์œจ์ ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

5000์„ ๋„ฃ์–ด๋„ ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์ง€ ์•Š๋Š”๋‹ค.

 

์˜ˆ์ œ 2 : ๋ณ‘ํ•ฉ์ •๋ ฌ(Merge Sort)

์ด์ œ ๋ถ„ํ• ์ •๋ณต์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ์ธ ๋ณ‘ํ•ฉ์ •๋ ฌ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž. ๋ณ‘ํ•ฉ ์ •๋ ฌ์˜ ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. 2๊ฐœ์”ฉ ๋ฌถ์ผ ๋•Œ ๊นŒ์ง€ ๋ฐ˜์œผ๋กœ ์ชผ๊ฐœ๋‚˜๊ฐ„๋‹ค.
  2. ๊ฐ ์š”์†Œ๋“ค์„ ์ •๋ ฌํ•˜๋ฉฐ ํ•ฉ์ณ๋‚˜๊ฐ„๋‹ค.(๋‘ ๋ฌถ์Œ์ด ๋  ๋•Œ ๊นŒ์ง€)
  3. 2์—์„œ ๋‚˜์˜จ ๋‘ ๋ฌถ์Œ์—์„œ ๋งจ ์•ž์„ ๋น„๊ตํ•ด ํฌ๊ธฐ๊ฐ€ ์ž‘์€ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฐฐ์น˜ํ•œ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์„ ๋ณด๋„๋ก ํ•˜์ž.

๋ถ„ํ• ๊ณผ์ •

๋ณ‘ํ•ฉ๊ณผ์ •

 

๋ถ„ํ• ๊ณผ์ •์„ ์ˆ˜ํ–‰ํ•  ๋•Œ์—๋Š” ๊ฐ ๋ฉ์–ด๋ฆฌ์˜ ๋งจ ์•ž์„ ๋น„๊ตํ•ด ๋” ์ž‘์€ ๊ฐ’์„ ๊ฐ€์ ธ์™€ ํ•ฉ์ณ๋‚˜๊ฐ€์•ผ ํ•œ๋‹ค.

๋ณ‘ํ•ฉ๊ณผ์ • ์ƒ์„ธ

 

์ด์ œ ์œ„ ๊ณผ์ •์„ ์ฝ”๋“œ๋กœ ์งœ ๋ณด๋„๋ก ํ•˜์ž.

#include<iostream>

using namespace std;

int arr[10];
int arr2[10];

void merge(int left, int right)
{
	int mid = (left + right) / 2;

	int i = left;
	int j = mid + 1;
	int k = left;
	while (i <= mid && j <= right)
	{
		if (arr[i] <= arr[j])
			arr2[k++] = arr[i++];
		else
			arr2[k++] = arr[j++];
	}

	int tmp = i > mid ? j : i;

	while (k <= right) arr2[k++] = arr[tmp++];

	for (int i = left; i <= right; i++) arr[i] = arr2[i];
}

void divide(int left, int right)
{
	int mid;
	if (left < right)
	{
		mid = (left + right) / 2;
		divide(left, mid);
		divide(mid + 1, right);
		merge(left, right);
	}
}

int main() {
	int a;
	for (int i = 0; i < 10; i++) {
		cin >> a;
		arr[i] = a;
	}
	

	divide(0, 9);

	for (int i = 0; i < 10; i++) {
		cout << arr2[i] << " ";
	}

	
}

 

10๊ฐœ์˜ ์ˆ˜๋ฅผ ๋ฐ›์•„ arr๋ฐฐ์—ด์— ๋„ฃ์–ด ๋ถ„ํ•  ์ •๋ ฌํ•œ ๋’ค arr2๋ฐฐ์—ด์— ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋Š” ์ฝ”๋“œ์ด๋‹ค.

 


์ด ๋ฌธ์ œ๋Š” ์ฒ˜์Œ ๋ณผ ๋•Œ๋Š” ์ƒ์†Œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด ๋ฌธ์ œ๋ฅผ ํ†ตํ•ด ๋ถ„ํ• ์ •๋ณต์„ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€ ํ•™์Šตํ•˜๊ณ  ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ํ’€์–ด๋‚˜๊ฐ€๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

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

 

2630๋ฒˆ: ์ƒ‰์ข…์ด ๋งŒ๋“ค๊ธฐ

์ฒซ์งธ ์ค„์—๋Š” ์ „์ฒด ์ข…์ด์˜ ํ•œ ๋ณ€์˜ ๊ธธ์ด N์ด ์ฃผ์–ด์ ธ ์žˆ๋‹ค. N์€ 2, 4, 8, 16, 32, 64, 128 ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ƒ‰์ข…์ด์˜ ๊ฐ ๊ฐ€๋กœ์ค„์˜ ์ •์‚ฌ๊ฐํ˜•์นธ๋“ค์˜ ์ƒ‰์ด ์œ—์ค„๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์ค„๊นŒ์ง€ ์ฃผ์–ด์ง„๋‹ค.

www.acmicpc.net

 

 

์•ž ๋‹จ๊ณ„์™€ ๋˜‘๊ฐ™์ด ํ’€ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ด๋‹ค. ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ์กฐ๊ธˆ ๋Š˜์–ด๋‚œ๋‹ค. ์•ž ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ–ˆ๋‹ค๋ฉด ๋ฌด๋ฆฌ์—†์ด ํ’€ ์ˆ˜ ์žˆ๋‹ค.

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

 

1780๋ฒˆ: ์ข…์ด์˜ ๊ฐœ์ˆ˜

N×Nํฌ๊ธฐ์˜ ํ–‰๋ ฌ๋กœ ํ‘œํ˜„๋˜๋Š” ์ข…์ด๊ฐ€ ์žˆ๋‹ค. ์ข…์ด์˜ ๊ฐ ์นธ์—๋Š” -1, 0, 1์˜ ์„ธ ๊ฐ’ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ํ–‰๋ ฌ์„ ์ ์ ˆํ•œ ํฌ๊ธฐ๋กœ ์ž๋ฅด๋ ค๊ณ  ํ•˜๋Š”๋ฐ, ์ด๋•Œ ๋‹ค์Œ์˜ ๊ทœ์น™์— ๋”ฐ๋ผ ์ž๋ฅด๋ ค๊ณ  ํ•œ๋‹ค.

www.acmicpc.net

 

 

์•ž ๋ฌธ์ œ์˜ ์‘์šฉํŒ๊ฐ™์€ ๋ฌธ์ œ์ด๋‹ค. ๋ฌธ์ œ ํ’€์ด ๋ฐฉ์‹์„ ์กฐ๊ธˆ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค. ์‹œ๊ฐ„ ์ œํ•œ์— ๊ฑธ๋ฆฌ์ง€ ์•Š๊ณ  ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•˜๋ฉฐ ํ’€์–ด๋ณด๋„๋ก ํ•˜์ž.

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

 

1074๋ฒˆ: Z

ํ•œ์ˆ˜๋Š” ํฌ๊ธฐ๊ฐ€ 2N × 2N์ธ 2์ฐจ์› ๋ฐฐ์—ด์„ Z๋ชจ์–‘์œผ๋กœ ํƒ์ƒ‰ํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 2×2๋ฐฐ์—ด์„ ์™ผ์ชฝ ์œ„์นธ, ์˜ค๋ฅธ์ชฝ ์œ„์นธ, ์™ผ์ชฝ ์•„๋ž˜์นธ, ์˜ค๋ฅธ์ชฝ ์•„๋ž˜์นธ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•˜๋ฉด Z๋ชจ์–‘์ด๋‹ค. ๋งŒ์•ฝ, N > 1์ด ๋ผ์„œ

www.acmicpc.net

 

๋Œ“๊ธ€