Skip to main content

Bitmasking

BOJ 5638 ์ˆ˜๋ฌธ

·209 words·1 min
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/5638 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # ๋Œ์— ์ˆ˜๋ฌธ์ด ์žˆ๊ณ , ์œ ๋Ÿ‰๊ณผ ํ”ผํ•ด๋น„์šฉ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ํ”ผํ•ด๋น„์šฉ์€ ์—ฌ๋Š” ์‹œ๊ฐ„์— ๋น„๋ก€ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฐ ์ˆ˜๋ฌธ์— ๋Œ€ํ•ด, ์œ ๋Ÿ‰์— ์‹œ๊ฐ„์„ ๊ณฑํ•ด์„œ ๊ฐ ์ˆ˜๋ฌธ์ด ๋ฒ„๋ฆด ์ˆ˜ ์žˆ๋Š” ๋ฌผ์˜ ์–‘์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ์— ๋”ฐ๋ฅธ ๊ฐ€๊ฒฉ์ด ๋‚˜์˜จ๋‹ค. ์ด๊ฑด ๊ทธ๋ฆฌ๋””ํ•˜๊ฒŒ๋Š” ์กฐ๊ธˆ ๊ณค๋ž€ํ•˜๊ณ , ๋ฐฐ๋‚ญ ๋ฌธ์ œ๋กœ ๋˜๋‚˜? ํ–ˆ๋Š”๋ฐ, $V$๊ฐ€ ๋„ˆ๋ฌด ํฌ๋‹ค! ๊ทธ๋Ÿฐ๋ฐ ์ˆ˜๋ฌธ์˜ ๊ฐœ์ˆ˜๊ฐ€ $n \leq 20$์œผ๋กœ ์œ ์˜๋ฏธํ•˜๊ฒŒ ์ž‘๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค์— ๋Œ€ํ•ด ๋ชจ๋“  ์ˆ˜๋ฌธ์„ ์—ด์–ด๋ณด๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ์‹œ๊ฐ„๋ณต์žก๋„ $O(2^n \cdot nm)$ ์ •๋„์— ๋™์ž‘ํ•  ๊ฒƒ ๊ฐ™๋‹ค. ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): void solve(){ int N; cin >> N; vector<pll> door(N); rep(i, 0, N) cin >> door[i].first >> door[i].second; int Q; cin >> Q; rep(q, 1, Q+1){ ll V, T; cin >> V >> T; ll ans = 1e18; rep(bit, 0, 1<<N){ ll wat = 0, cost = 0; rep(i, 0, N) if(bit & (1<<i)) wat += door[i].first*T, cost += door[i].second; if(wat >= V) ans = min(ans, cost); } cout << "Case " << q << ": "; if(ans == 1e18) cout << "IMPOSSIBLE\n"; else cout << ans << '\n'; } } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ

BOJ 15896 &+ +&

·510 words·3 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/15896 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # bitwise and๋“ค์˜ ํ•ฉ๊ณผ, ํ•ฉ๋“ค์˜ bitwise and ๊ฐ’์„ ๊ตฌํ•ด์•ผํ•œ๋‹ค. ์ผ๋‹จ ์•ž์—๊ป๋ถ€ํ„ฐ ํ•ด๋ณด์ž. $N$์€ 100๋งŒ??์ด๋‹ค. ๊ฐœํฌ๋„ค ๋ชจ๋“  $(A_i \& B_j)$์˜ ํ•ฉ์„ 1999๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€ ๋‚˜์ด๋ธŒํ•˜๊ฒŒ ์ œ๊ณฑ์€ ๋  ๋ฆฌ๊ฐ€ ์—†๋‹ค. bitwise and์˜ ํŠน์„ฑ์„ ์ƒ๊ฐํ•ด๋ณด์ž. $A_i$์—์„œ๋„, $B_j$์—์„œ๋„ ์ผœ์ ธ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๊ฐ ๋น„ํŠธ์— ๋Œ€ํ•ด์„œ ์ƒ๊ฐํ•˜๋ฉด, $A$์—์„œ ํ•ด๋‹น ๋น„ํŠธ๊ฐ€ ์ผœ์ง„ ๊ฐœ์ˆ˜ * $B$์—์„œ ํ•ด๋‹น ๋น„ํŠธ๊ฐ€ ์ผœ์ง„ ๊ฐœ์ˆ˜์™€ ๊ฐ™์ด ๊ตฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ์ „์ฒ˜๋ฆฌ์— $O(N\times29)$, ๊ณ„์‚ฐํ•˜๋Š”๋ฐ์— $O(29)$๊ฐ€ ๊ฑธ๋ฆด ๊ฒƒ ๊ฐ™๋‹ค. ๋ชจ๋“  $(A_iย +ย B_j)$์˜ bitwise and ์—ฐ์‚ฐ ๊ฐ’ ์ž ์ด์ œ ์ด๊ฒŒ ๋ฌธ์  ๊ฑฐ๊ฐ™์€๋ฐ… ํ•ฉ์ด ์ด์Šˆ๋‹ค. ๋ฐ›์•„์˜ฌ๋ฆผ์ด ์žˆ๋‹ค๋ณด๋‹ˆ ์กฐ๊ธˆ ์‹ ๊ฒฝ์“ฐ์ธ๋‹ค. ๋‹ค์‹œํ•œ๋ฒˆ bitwise and์˜ ํŠน์„ฑ์„ ์ƒ๊ฐํ•ด๋ณด์ž. ๋ชจ๋‘ ์ผœ์ ธ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š”๊ฑด, ๋ชจ๋“  ์ˆœ์„œ์Œ $(i, j)$์— ๋Œ€ํ•ด $A_i + B_j = C_k$๋ผ๊ณ  ํ• ๋•Œ, ์–ด๋–ค $C_k$์˜ ๋น„ํŠธ๊ฐ€ ๊บผ์ ธ์žˆ์œผ๋ฉด, ์ •๋‹ต์—์„œ ํ•ด๋‹น ๋น„ํŠธ๋Š” ๊บผ์ง„๋‹ค. ์ผ๋‹จ ์ฒซ๋ฒˆ์งธ ๋น„ํŠธ์— ๋Œ€ํ•ด์„œ๋Š” ์‰ฝ๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋”ํ–ˆ์„๋•Œ ๋ชจ๋‘ $1$์ด ๋‚จ๊ธฐ ์œ„ํ•ด์„  $1 + 0, 0 + 1$ ๋‘๊ฐ€์ง€๋งŒ ๊ฐ€๋Šฅํ•˜๊ธฐ์—, ๊ฐœ์ˆ˜๊ฐ€ $(N, 0), (0, N)$์ด ์•„๋‹ˆ๋ผ๋ฉด ๋น„ํŠธ๊ฐ€ ๊บผ์งˆ ์ˆ˜๋ฐ–์— ์—†๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๋‹น ์œ— ๋น„ํŠธ๋ถ€ํ„ฐ๋Š” ๋ฐ›์•„์˜ฌ๋ฆผ์ด ์ƒ๊ธด๋‹ค… $11_2 + 01_2 = 100_2$ ์™€ ๊ฐ™์ด $(1, 0)$์ด์—ˆ์Œ์—๋„ ๋น„ํŠธ๊ฐ€ ๊บผ์งˆ ์ˆ˜ ์žˆ๋‹ค. ํ˜น์€ $11_2 + 11_2 = 110_2$์™€ ๊ฐ™์ด $(1, 1)$์ด์—ˆ์œผ๋ฉ”๋„ ๋น„ํŠธ๊ฐ€ ์ผœ์งˆ ์ˆ˜ ์žˆ๋‹ค. ํ•˜ ์ด๊ฒŒ ๋ฌด์Šจ ์˜๋ฏธ์ง€? ์˜ˆ๋ฅผ๋“ค์–ด $4$์˜์ž๋ฆฌ ๋น„ํŠธ๊ฐ€ ์ผœ์ ธ์žˆ๋‚˜? ๋ผ๋Š” ์งˆ๋ฌธ์€ $8$๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€๋“ค์˜ ํ•ฉ์— ๋Œ€ํ•ด, ๋‚˜๋จธ์ง€๊ฐ€ ๋ชจ๋‘ $4$ ์ด์ƒ์ธ๊ฐ€? ํ•˜๋Š” ์งˆ๋ฌธ๊ณผ ๊ฐ™๊ธด ํ•˜๋‹ค. $0$$3$, $8$$11$์€ ์•ˆ๋œ๋‹ค๋Š”๊ฑฐ์ง€. ๊ทธ ์‚ฌ์ด์— ๊ฐ’์ด ์žˆ๋Š”์ง€ ์—†๋Š”์ง€๋ฅผ ์ฒดํฌํ•  ์ˆ˜๊ฐ€ ์žˆ๋‚˜? ์ผ๋ฐ˜ํ™”์‹œํ‚ค๋ฉด, $2^k$์˜ ๋น„ํŠธ๊ฐ€ ์ผœ์ ธ์žˆ๋Š”๊ฑด $\mod 2^{k+1}$ ์— ๋Œ€ํ•ด ๋‚˜๋ˆˆ ์• ๋“ค์˜ ํ•ฉ์— ๋Œ€ํ•ด $0 \leq s < 2^k$ ๋˜๋Š” $2^{k+1} \leq s < 2^{k+1} + 2^k$ ์ธ๊ฒŒ ์žˆ์œผ๋ฉด ์•ˆ๋œ๋‹ค. ์ด๊ฑธ ๊ฐ ๋น„ํŠธ์— ๋Œ€ํ•ด ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ๊ทธ๋ž˜๋„ ์ •๋ ฌํ•ด์„œ ์ด๋ถ„ํƒ์ƒ‰์œผ๋กœ ๊ตฌํ•  ์ˆœ ์žˆ์„๊ฑฐ๊ฐ™๊ธด ํ•œ๋ฐ…… $N$ ์ œํ•œ์ด 100๋งŒ์ด๋ผ $O(29 \times N\log{N})$์„ ํ•˜๋ฉด ์ฃฝ์—ฌ๋ฒ„๋ฆฌ๊ฒ ๋‹ค๋Š” ๋ง๊ณผ ๊ฐ™์€ ๊ฒƒ ๊ฐ™๋‹ค. ์–ด? ๊ทผ๋ฐ ๋‚ด๊ฐ€ ํ•„์š”ํ•œ๊ฑด, ๋น„ํŠธ๋‹จ์œ„๋กœ ํ•˜๋‚˜์”ฉ ํ™•์žฅํ•ด๋‚˜๊ฐ€๋ฉด์„œ ์ •๋ ฌํ•˜๋Š”๊ฑฐ๋‹ค. ์ด๊ฒŒ ๋ฐ”๋กœ Radix Sort ์•„๋‹Œ๊ฐ€? ๊ฒŒ๋‹ค๊ฐ€ ๋ฐฐ์—ด ๋‘๊ฐœ๋กœ ์ชผ๊ฐœ์ ธ์žˆ์„๋•Œ, ๋‹ค๋ฅธ ๋ฐฐ์—ด์—์„œ ํ•˜๋‚˜ํ•˜๋‚˜ ํ•ฉ์ด ์ € ์•ˆ์— ๋“ค์–ด์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š”๊ฑด ๊ทธ๋ฆฌ๋””ํ•˜๊ฒŒ 0/1๋กœ ์ชผ๊ฐœ์ง„ ๋‘ ๋ฐฐ์—ด์˜ ๋งจ์•ž/๋งจ๋’ค๋ฅผ ๋ณด๋Š”๊ฒƒ๋งŒ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋ฑ์„ ์ด์šฉํ•ด์„œ ๊ด€๋ฆฌํ•ด๋ณด์ž. ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): void solve(){ ll N; cin >> N; vector<ll> A(N), B(N); rep(i, 0, N) cin >> A[i]; rep(i, 0, N) cin >> B[i]; vector<ll> bitCountA(30), bitCountB(30); rep(i, 0, N) rep(j, 0, 30){ if((A[i] >> j) & 1) bitCountA[j]++; if((B[i] >> j) & 1) bitCountB[j]++; } ll ans1 = 0; rep(i, 0, 30){ ans1 += (1LL << i) % 1999 * (bitCountA[i] * bitCountB[i]) % 1999; ans1 %= 1999; } cout << ans1 << " "; ll ans2 = 0; vector<ll> dq[2], ndq[2]; dq[0].reserve(N); dq[1].reserve(N); ndq[0].reserve(N); ndq[1].reserve(N); rep(i, 0, N) dq[0].push_back(A[i]); rep(bit, 0, 30){ ndq[0].clear(); ndq[1].clear(); for(ll x: dq[0]) (x >> bit) & 1 ? ndq[1].push_back(x) : ndq[0].push_back(x); for(ll x: dq[1]) (x >> bit) & 1 ? ndq[1].push_back(x) : ndq[0].push_back(x); swap(dq[0], ndq[0]); swap(dq[1], ndq[1]); vector<ll> cand; if(!dq[0].empty()){ cand.push_back(dq[0].front()); cand.push_back(dq[0].back()); } if(!dq[1].empty()){ cand.push_back(dq[1].front()); cand.push_back(dq[1].back()); } bool flag = true; for(auto x: B) for(auto c: cand) if((((x+c) >> bit) & 1) == 0){ flag = false; break; } if(flag) ans2 += (1LL << bit); } cout << ans2 << "\n"; } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ

BOJ 17790 Inquiry II

·445 words·3 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/17790 ๋ฒˆ์—ญ ๋ฌธ์ œ # ๋ฌด๋ฐฉํ–ฅ ๋‹จ์ˆœ ๊ทธ๋ž˜ํ”„ G = (V, E)์— ๋Œ€ํ•ด, V’ โІ V์ธ ๋ถ€๋ถ„์ง‘ํ•ฉ V’๋ฅผ ๋…๋ฆฝ ์ง‘ํ•ฉ(independent set)์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์€ V’์˜ ์–ด๋–ค ๋‘ ์›์†Œ๋„ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๋•Œ์ž…๋‹ˆ๋‹ค. G์˜ ๋…๋ฆฝ ์ง‘ํ•ฉ์„ ์ตœ๋Œ€ ๋…๋ฆฝ ์ง‘ํ•ฉ(maximum independent set)์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ์€ G์— ๊ทธ๋ณด๋‹ค ์—„๊ฒฉํ•˜๊ฒŒ ๋” ๋งŽ์€ ์ •์ ์„ ๊ฐ€์ง„ ๋…๋ฆฝ ์ง‘ํ•ฉ์ด ์—†์„ ๋•Œ์ž…๋‹ˆ๋‹ค. ํŠน์ •ํ•œ ์ข…๋ฅ˜์˜ ์—ฐ๊ฒฐ๋œ ๊ทธ๋ž˜ํ”„ G๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, G์˜ ์ตœ๋Œ€ ๋…๋ฆฝ ์ง‘ํ•ฉ์˜ ํฌ๊ธฐ๋ฅผ ๊ตฌํ•˜์„ธ์š”.

BOJ 14939 ๋ถˆ ๋„๊ธฐ

·244 words·2 mins
๐Ÿ“ ๋ฌธ์ œ ์ •๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/14939 ๐Ÿง ๊ด€์ฐฐ ๋ฐ ์ ‘๊ทผ # ๋งจ ์œ—์ค„์„ ์–ด์ฐŒ์ €์ฐŒ ์ผ์ฒ˜๋ฆฌ๋ฅผ ๋๋ƒˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž. ๋‘๋ฒˆ์งธ ์ค„๋ถ€ํ„ฐ, ๊ทธ ์œ—์ค„์˜ ๋‚จ์€ ์ „๊ตฌ๋ฅผ ๋„๋Š” ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ์นธ ์•„๋ž˜์˜ ์Šค์œ„์น˜๋ฅผ ์ปจํŠธ๋กค ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์œ ์ผํ•˜๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งจ ์œ—์ค„์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• $= 2^{10} = 1024$๊ฐ€์ง€์— ๋Œ€ํ•ด ํ•ด๋ณผ ์ˆ˜ ์žˆ๊ณ , ์‹œ๋ฎฌ๋ ˆ์ด์…˜์€ $100 \times 100 = 10000$๋ฒˆ์œผ๋กœ ์ถฉ๋ถ„ํžˆ ์‹œ๊ฐ„ ๋‚ด๋กœ ๋“ค์–ด์˜จ๋‹ค. ๋งจ ์•„๋žซ์ค„์— ์ผœ์ง„ ์ „๊ตฌ๊ฐ€ ๋‚จ์•„์žˆ์œผ๋ฉด ์•ˆ๋จ์— ์œ ์˜ํ•œ๋‹ค. ๐Ÿ’ป ํ’€์ด # ์ฝ”๋“œ (C++): void solve(){ vector<string> board(10); rep(i, 0, 10) cin >> board[i]; int answer = 1e9; rep(bit, 0, 1<<10){ vector<string> cboard = board; int cnt = 0; auto press = [&](int r, int c){ cnt++; cboard[r][c] = (cboard[r][c] == 'O' ? 'X' : 'O'); if(r > 0) cboard[r-1][c] = (cboard[r-1][c] == 'O' ? 'X' : 'O'); if(r < 9) cboard[r+1][c] = (cboard[r+1][c] == 'O' ? 'X' : 'O'); if(c > 0) cboard[r][c-1] = (cboard[r][c-1] == 'O' ? 'X' : 'O'); if(c < 9) cboard[r][c+1] = (cboard[r][c+1] == 'O' ? 'X' : 'O'); }; rep(c, 0, 10) if(bit & (1 << c)) press(0, c); rep(r, 1, 10) rep(c, 0, 10) if(cboard[r-1][c] == 'O') press(r, c); bool ok = true; rep(c, 0, 10) if(cboard[9][c] == 'O') ok = false; if(ok) answer = min(answer, cnt); } if(answer == 1e9) cout << -1 << '\n'; else cout << answer << '\n'; } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ