2021. 11. 27. 12:36ใProgramming/Algorithms
1. ๋ฌธ์
๊ณ๋ ํ ๊ฐ์ _ _ _ _ _ _ _ _ _ _ _ _ _ ์จ๋ธ๋ฐ์ง ๋ฌ๋ฌ!
๊ณํ ๊ฒฝ์ ์ ์คํจ๋ก ์ธ๊ณ ์ต๊ณ ์ ์ธํ๋ ์ด์ ์ ์๋ํ๊ฒ ๋ ๊ณต์ฐ ๊ตญ๊ฐ ์จ๋ธ๋ฐ์ง์์๋ ํ๋ฃจ ์ค์๋ ๋ฌผ๊ฐ๊ฐ ๊ณ์ ์ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋ฌผ๊ฑด์ ๊ฐ๊ฒฉ์ ์ค์๊ฐ์ผ๋ก ๋ฐ๊ฟ์ผ ํฉ๋๋ค. ์จ๋ธ๋ฐ์ง์์ ๊ฐ์ฅ ํฐ ๋ฌด๊ฐ๋ฒ ๋งํธ์์๋ ๊ทธ๋์ ์์ ๊ฐ์ด ๋น ์นธ๋ง ์ฐ์ฌ ์๋ ๊ด๊ณ ํ์ ๋ถ์ฌ๋๊ณ ๊ณ๋ ๊ฐ๊ฒฉ์ด ์ค๋ฆ์ ๋ฐ๋ผ (์ ํํ๋ ์จ๋ธ๋ฐ์ง ๋ฌ๋ฌ์ ๊ฐ์น๊ฐ ์ถ๋ฝํจ์ ๋ฐ๋ผ) ์ค์๊ฐ์ผ๋ก ์ซ์๊ฐ ํฌ๊ฒ ์ ํ ํ๋ผ์คํฑ ํ์ ๋น ์นธ์ ๊ฐ์ ๋ผ์๋๋ค. ์๋ฅผ ๋ค์ด ๊ณ๋ ํ ๊ฐ์ 35์ต ์จ๋ธ๋ฐ์ง ๋ฌ๋ฌ๋ผ๊ณ ํ๋ฉด, 3์ด ์ฐ์ธ ํ ํ ๊ฐ, 5๊ฐ ์ฐ์ธ ํ ํ ๊ฐ, 0์ด ์ฐ์ธ ํ ์ฌ๋ ๊ฐ๋ฅผ ๋น์นธ์ ์์๋๋ก ๋ผ์ฐ๋ ๊ฒ์ด์ฃ .
๋ฌด๊ฐ๋ฒ ๋งํธ์์ ์๋ฅด๋ฐ์ดํธ๋ฅผ ํ๋ ์ข ์ฑ์ด๋ ์ด๋ ๋ ๊ณค๋ํ ์๋์ ๋ง์์ต๋๋ค. ์ด ์๋์ ์๊น ์ฌ ๊ฐ๋ ๊ณ๋์ ํ๋ถํ๊ฒ ๋ค๊ณ ๋์์๋๋ฐ, ์์์ฆ์ ์์ด๋ฒ๋ฆฐ๋ฐ๋ค ๊ณ๋์ ์ผ๋ง์ ์๋์ง๋ฅผ ๊ธฐ์ตํ์ง๋ ๋ชปํ๋ค๊ณ ํ๋๊ตฐ์. ๊ณ๋ ๊ฐ์ ๊ทธ ์ฌ์ด ํ ๋ฒ ๋ ์ฌ๋๊ธฐ ๋๋ฌธ์ ๊ด๊ณ ํ์ ์ ํ ๊ฐ๊ฒฉ์ ์ด๋ฏธ ๋ฐ๋ ๋ค์ ๋๋ค. ๋คํํ ์ข ์ฑ์ด๋ ๋ ๊ฐ์ง๋ฅผ ๊ธฐ์ตํฉ๋๋ค.
- ๋ง์ง๋ง์ ๊ณ๋ ๊ฐ๊ฒฉ์ด ์ฌ๋์ ๋, ์ข ์ฑ์ด๋ ๊ด๊ณ ํ์ ๊ฝํ ํ๋ผ์คํฑ ํ์ ์์๋ง ๋ฐ๊ฟจ์ต๋๋ค. ๋ค๋ฅธ ํ๋ผ์คํฑ ํ์ ๊ฐ์ ธ์ค๊ฑฐ๋ ์๋ ํ๋ผ์คํฑ ํ์ ๋บ ์ผ์ ์์๋ค๋ ๊ฒ์ด์ฃ .
- ๋ง์ง๋ง ๊ณ๋ ๊ฐ๊ฒฉ์ ๋ณด๋ฉด์ '์ ์ด๊ฑฐ๋ฉด ์ ํํ ์ฌํ m๊ฐ๋ฅผ ์ด ์ ์๊ตฌ๋' ๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๋ฐ๋ผ์ ๋ง์ง๋ง ๊ณ๋ ๊ฐ๊ฒฉ์ m์ ๋ฐฐ์์์ต๋๋ค. (์ฌํ ๊ฐ๊ฒฉ๋ ์ด๋ฏธ ์ฌ๋๊ธฐ ๋๋ฌธ์ ์ด๊ฑธ ๊ฐ์ง๊ณ ๊ณ๋ ๊ฐ๊ฒฉ์ ๊ณ์ฐํ ์๋ ์์ต๋๋ค)
์ง๊ธ ๊ณ๋ ๊ฐ๊ฒฉ e์ m์ด ์ฃผ์ด์ง ๋ ๊ฐ๋ฅํ ์ด์ ๊ณ๋ ๊ฐ๊ฒฉ์ด ๋ช ๊ฐ์ง๋ ์๋์ง ๊ณ์ฐํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์. ์ด์ ๊ณ๋ ๊ฐ๊ฒฉ์ e ๋ณด๋ค ํญ์ ์์์ผ ํฉ๋๋ค.
2. ํ์ด
2-1. ๋จ์ ํด๋ต
// ์จ๋ฐ๋ธ์ง ๋ฌธ์ ์ ๋ต์ ๋ชจ๋ ์ฐพ๋ ์์ ํ์ ์๊ณ ๋ฆฌ์ฆ
string e;
string digits;
int n;
int m;
void generate(string price, bool taken[15]) {
if (price.size() == n) {
if (price < e) {
cout << price << endl;
}
return;
}
for (int i = 0; i < n; ++i) {
if (!taken[i] && (i == 0 || digits[i - 1] != digits[i] || taken[i - 1])) {
taken[i] = true;
generate(price + digits[i], taken);
taken[i] = false;
}
}
}
// ์จ๋ฐ๋ธ์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋์ ๊ณํ๋ฒ ์๊ณ ๋ฆฌ์ฆ
const int MOD = 1000000007;
string e;
string digits;
int n;
int m;
int cache[1 << 14][20][2];
int price(int index, int taken, int mod, int less) {
if (index == n) {
return (less && mod == 0) ? 1 : 0;
}
int& ret = cache[taken][mod][less];
if (ret != -1) {
return ret;
}
ret = 0;
for (int next = 0; next < n; ++next) {
if ((taken & (1 << next)) == 0) {
if (!less && e[index] < digits[next]) {
continue;
}
if (next > 0 && digits[next - 1] == digits[next] && (taken & (1 << (next - 1))) == 0) {
continue;
}
int nextTaken = taken | (1 << next);
int nextMod = (mod * 10 + digits[next] - '0') % m;
int nextLess = less || e[index] > digits[next];
ret += price(index + 1, nextTaken, nextMod, nextLess);
ret %= MOD;
}
}
return ret;
}
2-2. ๋ฌธ์ ํ์ด
// ์จ๋ฐ๋ธ์ง ๊ณ๋ ๊ฐ๊ฒฉ์ ์ฐพ์๋ณด์!
/* ์จ๋ฐ๋ธ์ง ๋ฌธ์ ์ ๋ต์ ๋ชจ๋ ์ฐพ๋ ์์ ํ์ ์๊ณ ๋ฆฌ์ฆ
์ด์ ๊ณ๋ ๊ฐ๊ฒฉ์ ๋ค์ ์ธ๊ฐ์ง ์กฐ๊ฑด์ ๋ง์กฑํด์ผ ํ๋ค.
1. ์ ๊ณ๋ ๊ฐ๊ฒฉ e์ ํฌํจ๋ ์ซ์๋ค์ ์ฌ๋ฐฐ์ดํ ๊ฒฐ๊ณผ
2. ์ ๊ณ๋ ๊ฐ๊ฒฉ e๋ณด๋ค ์์์ผ ํ๋ค.
3. m์ผ๋ก ๋๋์ด ๋จ์ด์ ธ์ผ ํ๋ค.
[์ฌ์ฉํ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ]
e์ ๊ฐ ์๋ฆฟ์๋ฅผ ์ ๋ ฌํด์ digits์ ์ ์ฅํ ๋ค์
์ด๋ฒ์ ์ฌ์ฉํ ์๋ฆฟ์ ๋ฐ๋ก ์ ์๋ฆฌ๊ฐ,
1. ์๊ฑฐ๋ (i = 0)
2. ์ด๋ฒ ์๋ฆฟ์๋ ๋ค๋ฅด๊ฑฐ๋ (digits[i - 1] != digits[i])
3. ์ด๋ฏธ ์ฌ์ฉ๋จ (taken[i - 1] = true)
์์ ๊ฐ์ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค.
- digits : e์ ์๋ฆฟ์๋ค์ ์ ๋ ฌํ ๋ฐฐ์ด
- price : ์ง๊ธ๊น์ง ๋ง๋ ๊ฐ๊ฒฉ
- taken : ๊ฐ ์๋ฆฟ์์ ์ฌ์ฉ ์ฌ๋ถ (boolean)
+ e๋ฅผ string์ผ๋ก ์ ์ธํ ์ด์
: ์๋ฆฟ์ ๋จ์๋ก ์ซ์๋ฅผ ๋ค๋ฃจ๋ ๊ฒฝ์ฐ, ๋ฌธ์์ด์ด ํจ์ฌ ๊ฐํธํ๋ค.
*/
string e;
string digits;
int n;
int m;
void generate(string price, bool taken[15]) {
if (price.size() == n) {
if (price < e) {
cout << price << endl;
// ๋ ๋ค ๋ฌธ์์ด์ด์ง๋ง, ์๋ฆฟ์๊ฐ ๊ฐ๊ธฐ์ price์ e๋ฅผ ๋น๊ตํ ์ ์๋ค. wow
}
return;
// ๊ธฐ์ ์ฌ๋ก : ๊ณ๋์ ๊ฐ๊ฒฉ์ ์ฐพ์๋ค!
}
for (int i = 0; i < n; ++i) {
if (taken[i] == false
&& (i == 0 || digits[i - 1] != digits[i] || taken[i - 1] = true))
{
taken[i] = true;
generate(price + digits[i], taken);
taken[i] = false;
}
}
}
/* ์จ๋ฐ๋ธ์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋์ ๊ณํ๋ฒ ์๊ณ ๋ฆฌ์ฆ
- ์๋ฆฟ์๋ฅผ ์ํด ๋ฌธ์์ด์ ์ฌ์ฉํ์ผ๋, ์ด๋ก ์ธํ์ฌ ๋ฉ๋ชจ์ด์ ์ด์
์ด ๊น๋ค๋ก์์ก๋ค.
- boolean ๊ฐ์ธ taken์ ๋นํธ๋ง์คํฌ๋ฅผ ํตํ์ฌ ์ ์๋ก ๋ณํ ๊ฐ๋ฅํ๋ค.
- but, ๋ฌธ์์ด price๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
ํ๋ ๊ฒ์ ๊น๋ค๋กญ๋ค.
: ๊ฐ์ price๋ฅผ ๋ ๋ฒ ๋ง๋ค ์ผ์ ์๊ธฐ ๋๋ฌธ์ price๋ฅผ ๊ทธ๋๋ก ๋ฉ๋ชจ์ด์ ์ด์
์ ์ฌ์ฉํ๋ฉด
์ค๋ณต๋๋ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ํ๋๋ ์์.
- ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ํด๋น ์์
์ ํ๋ ์ต์ํ์ ์ ๋ณด๋ง ์ฌ๊ท ํธ์ถ์ ์ ๋ฌ!
: ๊ทธ๋์ผ ์ค๋ณต ๋ฌธ์ ๊ฐ ๋ง์ด ์๊ฒจ์, ๋ฉ๋ชจ์ด์ ์ด์
์ ์ต๋ํ ํ์ฉํ ์ ์์ผ๋๊น.
[์ง๊ธ๊น์ง ๋ง๋ ๊ฐ๊ฒฉ์ธ price๊ฐ ์ฌ์ฉ๋๋ ๋ถ๋ถ]
1. n ์๋ฆฌ๋ฅผ ๋ชจ๋ ๊ตฌ์ฑํ๋์ง ํ๋จํ ๋
2. ๋ค ๋ง๋ ๊ฐ๊ฒฉ์ด ์ฌํ ๊ฐ๊ฒฉ์ ๋ฐฐ์์ธ์ง ํ๋จํ ๋
3. ๋ค ๋ง๋ ๊ฐ๊ฒฉ์ด ๋์ค ๊ฐ๊ฒฉ๋ณด๋ค ์์์ง ํ์ธํ ๋
1๋ฒ์ taken์ ๋ชจ๋ ์์๊ฐ true์ธ์ง ํ๋ณํ๋ ๊ฒ์ผ๋ก ๋์ฒด ๊ฐ๋ฅ : okay
2๋ฒ -> ๊ฐ๊ฒฉ์ด ์ค๋ฅธ ๊ฒ์ด ๋ง๋๊ฐ?
: ์ฐ๋ฆฌ๊ฐ ์์ผ๋ก ๋๋์
์ ํ๋ ๊ณผ์ ์ ์ดํด๋ณด๋ฉด,
ex) 7284 ๋์ 13284๊ฐ 7๋ก ๋๋์ด ๋จ์ด์ง๋ ์ง ํ์ธํ๋ ๊ณผ์
๋๋จธ์ง๊ฐ ๊ฐ๋ค๋ฉด ์์ ์ด๋ค ์๊ฐ ์๋์ง๋ ์ค์ํ์ง ์๋ค.
์ฆ, price๋ฅผ ์ ๋ฌํ๋ ๋์ , price๋ฅผ m์ผ๋ก ๋๋ ๋๋จธ์ง๋ฅผ ์ ๋ฌํ์.
: ๋ง์ง๋ง์ price๊ฐ m์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ ์ง ํ๋ณํ๋ ๋ฐ๋ ์ง์ฅX
: m์ผ๋ก ๋๋ ๋๋จธ์ง๋ 0๋ถํฐ m-1๊น์ง! ๋ฐ๋ผ์ ๋ฉ๋ชจ์ด์ ์ด์
๊ฐ๋ฅ!
3๋ฒ -> ์ฌํ ๊ฐ๊ฒฉ์ ๋ฐฐ์๊ฐ ๋ง๋๊ฐ?
๊ณ๋์ ์ ๊ฐ๊ฒฉ e๊ฐ 231 ์ด๋ผ๊ณ ๊ฐ์ ํด๋ณด์.
์ด๋ ์ฒซ ์๋ฆฌ์ ๋ค์ด๊ฐ ์ ์๋ ์๋ ์ด 3๊ฐ
1: ์์ผ๋ก ์ด๋ป๊ฒ ๋ฐฐ์นํ๋ ์ด ์๋ 231๋ณด๋ค ์์
2: ์์ผ๋ก ์ด๋ป๊ฒ ๋ฐฐ์นํ๋๋์ ๋ฐ๋ผ ์ด ์๋ 231๋ณด๋ค ํฌ๊ฑฐ๋ ์์
3: ์์ผ๋ก ์ด๋ป๊ฒ ๋ฐฐ์นํ๋ ์ด ์๋ 231๋ณด๋ค ํผ
: ๋ฐ๋ผ์ 1 OR 2 ์ ๊ฒฝ์ฐ๋ง ๊ฐ๋ฅํ๋ค. (์ด์ ์ ๊ณ๋ ๊ฐ๊ฒฉ์ ๋ ์ ๋ ดํด์ผ ํ๋๊น)
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ฌ๊ท ํธ์ถ์
- price๋ ์ด๋ฏธ e๋ณด๋ค ์์ผ๋ ๋๋จธ์ง๋ ์๋ฌด๋ ๊ฒ๋ ํด๋ผ(1์ ๊ฒฝ์ฐ) OR
- price๋ e๋ณด๋ค ์ปค์ง ์ ์์ผ๋ ์ฃผ์ํด๋ผ (2์ ๊ฒฝ์ฐ)
๋ผ๋ ์ ๋ณด๋ง ์ ๋ฌํ๋ฉด ๋๋ค.
์ดํ ๋ชจ๋ ์๋ฆฌ๋ฅผ ๊ตฌ์ฑํ์ ๋, price๊ฐ e๋ณด๋ค ์์์ง ์๋์ง๋ฅผ
boolean ๊ฐ less๋ก ํํํ๋ค.
- less = true : ์๋ถ๋ถ๋ณด๋ค ์์ผ๋ฏ๋ก, ํญ์ e๋ณด๋ค ์์ ์ํ
= less = false : price์ e์ ์๋ถ๋ถ์ด ์ผ์นํ๋ค.
- price : ์ง๊ธ๊น์ง ๋ง๋ ๊ฐ๊ฒฉ
- index : ์ด๋ฒ์ ์ฑ์ธ ์๋ฆฌ์ ์ธ๋ฑ์ค
- taken : ์ง๊ธ๊น์ง ์ฌ์ฉํ ์๋ฆฟ์๋ค์ ์งํฉ
- mod : price์ m์ ๋ํ ๋๋จธ์ง
- less : price๊ฐ ์ด๋ฏธ e๋ณด๋ค ์์ผ๋ฉด 1, ์๋๋ฉด 0 (boolean)
*/
const int MOD = 1000000007;
string e;
string digits;
int n;
int m;
int cache[1 << 14][20][2];
int price(int index, int taken, int mod, int less) {
if (index == n) {
if (less == true && mod == 0) {
return 1;
}
else {
return 0;
}
}
// ๋ฉ๋ชจ์ด์ ์ด์
int& ret = cache[taken][mod][less];
if (ret != -1) {
return ret;
}
ret = 0;
for (int next = 0; next < n; ++next) {
if ((taken == true & (1 << next)) == 0) {
if (less == false && (e[index] < digits[next])) {
// ๊ณผ๊ฑฐ ๊ฐ๊ฒฉ์ ํญ์ ์๋ก์ด ๊ฐ๊ฒฉ๋ณด๋ค ์์์ผ ํจ.
continue;
}
if (next > 0 && digits[next - 1] == digits[next] && (taken & (1 << (next - 1))) == 0) {
// ๊ฐ์ ์ซ์๋ ํ ๋ฒ๋ง ์ ํ
continue;
}
int nextTaken = taken | (1 << next);
int nextMod = (mod * 10 + digits[next] - '0') % m;
int nextLess = less || e[index] > digits[next];
ret += price(index + 1, nextTaken, nextMod, nextLess);
ret %= MOD;
}
}
return ret;
}
/*
[๋นํธ ์ฐ์ฐ์ ์ ๋ฆฌ]
<< X : X๋งํผ ์ผ์ชฝ์ผ๋ก ๋นํธ๋ค ์ด๋
>> X : X๋งํผ ์ค๋ฅธ์ชฝ์ผ๋ก ๋นํธ๋ค ์ด๋
~ : ๋นํธ๋ค์ ๋ฐ์ ์ํจ๋ค. (๋ค ๋ฐ๋๋ก, ๋ณด์)
& (AND) : ๋์๋๋ ๋นํธ๊ฐ ๋ชจ๋ 1์ผ ๋ 1์ด๋ค.
| (OR) : ๋์๋๋ ๋นํธ๊ฐ ๋ชจ๋ 0์ผ ๋ 0์ด๋ค.
^ (XOR) : ๋ ๋นํธ๊ฐ ๋ฌ๋ผ์ผ 1์ด๋ค. (๋์ด ๊ฐ์ผ๋ฉด 0)
*/
3. ๋๋์
1. ์ด๋ ต๋ค.
2. ๋ฉ๋ชจ์ด์ ์ด์ ์ ๋ค๋ฃจ๋ ์๋ก์ด ๊ด์
3. ๋ฌผ๊ฑด์ ์ด ๋๋ ์์์ฆ์ ๊ผญ ์ฑ๊ธฐ์..
4. git-hub ๋งํฌ
5. ์ถ์ฒ
- https://algospot.com/judge/problem/read/ZIMBABWE
- https://genesis8.tistory.com/130
'Programming > Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ํ์ด] STRJOIN ๋ฌธ์์ด ํฉ์น๊ธฐ / ํํ๋ง ์ฝ๋ (0) | 2021.11.30 |
---|---|
[์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ํ์ด] NUMBERGAME : ์ซ์ ๊ฒ์ (0) | 2021.11.28 |
[์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ํ์ด] TICTACTOE game (0) | 2021.11.28 |
[์๊ณ ๋ฆฌ์ฆ] ๋์ ๊ณํ๋ฒ, ๋ฉ๋ชจ์ด์ ์ด์ ์ด๋? (0) | 2021.11.27 |