From 4e09a7813ed2b30d9c700257747a5cc69c2bf9e5 Mon Sep 17 00:00:00 2001 From: yuyu0830 Date: Tue, 26 Mar 2024 15:08:38 +0900 Subject: [PATCH 1/2] =?UTF-8?q?24-03-26=20=ED=96=89=EB=A0=AC=20=EC=A0=9C?= =?UTF-8?q?=EA=B3=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuyu0830/README.md | 1 + .../10830.cpp" | 73 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 "yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" diff --git a/yuyu0830/README.md b/yuyu0830/README.md index 66dd712..b957bf0 100644 --- a/yuyu0830/README.md +++ b/yuyu0830/README.md @@ -5,4 +5,5 @@ | 1차시 | 2024.03.11 | 탐색 | [웜홀](https://www.acmicpc.net/problem/1865) | - | | 2차시 | 2024.03.15 | 탐색 | [숨바꼭질 2](https://www.acmicpc.net/problem/12851) | - | | 3차시 | 2024.03.20 | 탐색 | [하이퍼 토마토](https://www.acmicpc.net/problem/17114) | - | +| 4차시 | 2024.03.26 | 분할정복 | [행렬 제곱](https://www.acmicpc.net/problem/10830) | - | --- diff --git "a/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" "b/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" new file mode 100644 index 0000000..79e64e8 --- /dev/null +++ "b/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" @@ -0,0 +1,73 @@ +#include + +using namespace std; + +#define POW(a) a * a + +int n = 0; + +int crit[5][5], arr[5][5], tmp[5][5]; + +int calc(int x, int y, bool e) { + // x, y 포지션의 행렬 곱 결과 연산 함수 + int v = 0; + for (int i = 0; i < n; i++) { + // e 여부에 따라 Doubling을 할지, Adding를 할지 결정 + v += arr[x][i] * (e ? arr[i][y] : crit[i][y]); + v %= 1000; + } + + return v; +} + +void DoublingAdding(bool e) { + // 행렬의 각 위치별로 곱연산 시행 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + tmp[i][j] = calc(i, j, e); + } + } + + // tmp 배열 복사 + copy(&tmp[0][0], &tmp[0][0] + 25, &arr[0][0]); +} + +int main() { + long long int b = 0; + cin >> n >> b; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> arr[i][j]; + crit[i][j] = arr[i][j]; + } + } + + bool e[200]; + int cnt = 0; + + // 제곱할 수 b 분해 + while (b != 1) { + if (b % 2 == 0) { + b /= 2; + e[cnt] = 1; + } + else { + b -= 1; + e[cnt] = 0; + } + cnt++; + } + + for (int i = cnt - 1; i >= 0; i--) { + // 분해한 b를 토대로 Doubling 혹은 Adding 실행 + DoublingAdding(e[i]); + } + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + printf("%d ", arr[i][j] % 1000); + } + printf("\n"); + } +} \ No newline at end of file From 2b4c1ea6a29b153cc682c430b5d57939b7402cad Mon Sep 17 00:00:00 2001 From: yuyu0830 Date: Tue, 26 Mar 2024 16:14:37 +0900 Subject: [PATCH 2/2] =?UTF-8?q?24-03-26=20=EC=BD=94=EB=93=9C=20=EC=82=B4?= =?UTF-8?q?=EC=A7=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../10830.cpp" | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git "a/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" "b/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" index 79e64e8..d9db99f 100644 --- "a/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" +++ "b/yuyu0830/\353\266\204\355\225\240\354\240\225\353\263\265/10830.cpp" @@ -2,9 +2,8 @@ using namespace std; -#define POW(a) a * a - int n = 0; +long long int b = 0; int crit[5][5], arr[5][5], tmp[5][5]; @@ -22,18 +21,15 @@ int calc(int x, int y, bool e) { void DoublingAdding(bool e) { // 행렬의 각 위치별로 곱연산 시행 - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) tmp[i][j] = calc(i, j, e); - } - } // tmp 배열 복사 copy(&tmp[0][0], &tmp[0][0] + 25, &arr[0][0]); } int main() { - long long int b = 0; cin >> n >> b; for (int i = 0; i < n; i++) { @@ -43,25 +39,20 @@ int main() { } } - bool e[200]; - int cnt = 0; + long long int pointer = 137438953472; // 2^38 - // 제곱할 수 b 분해 - while (b != 1) { - if (b % 2 == 0) { - b /= 2; - e[cnt] = 1; - } - else { - b -= 1; - e[cnt] = 0; - } - cnt++; - } + // b와 비교할 수 있는 위치로 포인터 세팅 + while (!(b & pointer)) pointer = pointer >> 1; + pointer = pointer >> 1; + + // 앞에서부터 bit 연산으로 1인지 0인지 판단 + while (pointer) { + DoublingAdding(1); - for (int i = cnt - 1; i >= 0; i--) { - // 분해한 b를 토대로 Doubling 혹은 Adding 실행 - DoublingAdding(e[i]); + if (b & pointer) // 1이면 Adding 연산 추가 수행 + DoublingAdding(0); + + pointer = pointer >> 1; // bit Shift } for (int i = 0; i < n; i++) {