๋ฌธ์
๊ฐ์ฅ ๋ฉค๋ฒ๊ฐ ๋ง์ ์์ด๋ ๊ทธ๋ฃน์ผ๋ก ๊ธฐ๋ค์ค ๋ถ์ ์ฌ๋ผ ์๋ ํผ์ฑ ํ ๊ทธ๋ฃน ํ์ดํผ์๋์ด๊ฐ ๋ฐ๋ท 10์ฃผ๋ ๊ธฐ๋ ํฌ ๋ฏธํ ์ ๊ฐ์ตํ์ต๋๋ค. ํฌ ๋ฏธํ ์ ํ ์์๋ก, ๋ฉค๋ฒ๋ค๊ณผ ์ฐธ๊ฐํ ํฌ๋ค์ด ํฌ์น์ ํ๋ ํ์ฌ๋ฅผ ๊ฐ๊ธฐ๋ก ํ์ต๋๋ค. ํ์ดํผ์๋์ด์ ๋ฉค๋ฒ๋ค์ ์ฐ์ ๋ฌด๋์ ์ผ๋ ฌ๋ก ์ญ๋๋ค. ํฌ ๋ฏธํ ์ ์ฐธ๊ฐํ M๋ช ์ ํฌ๋ค์ ์ค์ ์์ ๋งจ ์ค๋ฅธ์ชฝ ๋ฉค๋ฒ์์๋ถํฐ ์์ํด ํ ๋ช ์ฉ ์ผ์ชฝ์ผ๋ก ์์ง์ด๋ฉฐ ๋ฉค๋ฒ๋ค๊ณผ ํ๋์ฉ ํฌ์น์ ํฉ๋๋ค. ๋ชจ๋ ํฌ๋ค์ ๋์์ ํ ๋ช ์ฉ ์์ง์ ๋๋ค. ์๋ ๊ทธ๋ฆผ์ ํ์ฌ ๊ณผ์ ์ ์ผ๋ถ๋ฅผ ๋ณด์ฌ์ค๋๋ค. a~d๋ ๋ค ๋ช ์ ํ์ดํผ์๋์ด ๋ฉค๋ฒ๋ค์ด๊ณ , 0~5๋ ์ฌ์ฏ ๋ช ์ ํฌ๋ค์ ๋๋ค.
ํ์ง๋ง ํ์ดํผ์๋์ด์ ๋จ์ฑ ๋ฉค๋ฒ๋ค์ด ๋จ์ฑ ํฌ๊ณผ ํฌ์นํ๊ธฐ๊ฐ ๋ฏผ๋งํ๋ค๊ณ ์ฌ๊ฒจ์, ๋จ์ฑ ํฌ๊ณผ๋ ํฌ์น ๋์ ์ ์๋ฅผ ํ๊ธฐ๋ก ํ์ต๋๋ค. ์ค์ ์ ๋ฉค๋ฒ๋ค๊ณผ ํฌ๋ค์ ์ฑ๋ณ์ด ๊ฐ๊ฐ ์ฃผ์ด์ง ๋ ํฌ ๋ฏธํ ์ด ์งํ๋๋ ๊ณผ์ ์์ ํ์ดํผ์๋์ด์ ๋ชจ๋ ๋ฉค๋ฒ๊ฐ ๋์์ ํฌ์น์ ํ๋ ์ผ์ด ๋ช ๋ฒ์ด๋ ์๋์ง ๊ณ์ฐํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์.
์ ๋ ฅ
์ฒซ ์ค์ ํ ์คํธ ์ผ์ด์ค์ ๊ฐ์ C (C≤20)๊ฐ ์ฃผ์ด์ง๋๋ค. ๊ฐ ํ ์คํธ ์ผ์ด์ค๋ ๋ฉค๋ฒ๋ค์ ์ฑ๋ณ๊ณผ ํฌ๋ค์ ์ฑ๋ณ์ ๊ฐ๊ฐ ๋ํ๋ด๋ ๋ ์ค์ ๋ฌธ์์ด๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ๊ฐ ๋ฌธ์์ด์ ์ผ์ชฝ๋ถํฐ ์ค๋ฅธ์ชฝ ์์๋๋ก ๊ฐ ์ฌ๋๋ค์ ์ฑ๋ณ์ ๋ํ๋ ๋๋ค.
M์ ํด๋นํ๋ ์ฌ๋์ด ๋จ์, F๋ ํด๋นํ๋ ์ฌ๋์ด ์ฌ์์์ ๋ํ๋ ๋๋ค. ๋ฉค๋ฒ์ ์์ ํฌ์ ์๋ ๋ชจ๋ 1 ์ด์ 200,000 ์ดํ์ ์ ์์ด๋ฉฐ, ๋ฉค๋ฒ์ ์๋ ํญ์ ํฌ์ ์ ์ดํ์ ๋๋ค.
์ถ๋ ฅ
๊ฐ ํ ์คํธ ์ผ์ด์ค๋ง๋ค ํ ์ค์ ๋ชจ๋ ๋ฉค๋ฒ๋ค์ด ํฌ์น์ ํ๋ ์ผ์ด ๋ช ๋ฒ์ด๋ ์๋์ง ์ถ๋ ฅํฉ๋๋ค.
ํ ์คํธ์ผ์ด์ค
4
fffmmm
mmmfff
fffff
ffffffffff
ffffm
fffffmmmmf
mfmfmfffmmmfmf
mmfffffmfffmffffffmfffmffffmfmmfffffff
1
6
2
2
๋์ ๋ต
- ๋จ์ํ ๊ณ์ฐ
def transToInt(tmp_list):
for i in range(len(tmp_list)):
if tmp_list[i]=="F"or tmp_list[i]=="f":
tmp_list[i]=1
else:
tmp_list[i]=0
return tmp_list
def HowMuchHug():
length = len(mem_list)
hug_num = 0
for i in range(len(fan_list)-len(mem_list)+1):
tmp = 1
for j in range(i,i+length):
if not(mem_list[j-i] or fan_list[j]):
tmp = 0 # ํฌ์น ์ ํ ์ฌ๋ ์์!
if tmp==1:
hug_num+=1
# 2* 10^(5)
return hug_num
c = int(input())
result = list()
for _ in range(c):
mem_list = transToInt(list(input()))
fan_list = transToInt(list(input()))
result.append(HowMuchHug())
for obj in result:
print(obj)
๋น์ฐํ ์๊ฐ์ด๊ณผ
- 2์ง์๋ก ๋ณํํ์ฌ ๋นํธ ์ฐ์ฐ์ ์ฌ์ฉ
def transToInt(l): # 2์ง์๋ก ๋ณํ
for i in range(len(l)):
if l[i]=="F":
l[i]='1'
else:
l[i]='0'
l = ''.join(l)
return l
c = int(input())
result = list()
for _ in range(c):
tmp_res = 0
mem_list = list(input())
exact_num = pow(2,len(mem_list)) # ๋์์ผํ๋ ์
mem_num = int(transToInt(mem_list),base=2) # member list๋ฅผ 2์ง์๋ก ๋ณํ
fan_list = list(input())
fan_num = transToInt(fan_list)
for i in range(len(fan_list)-len(mem_list)+1): # O(n-m)
tmp = (int(fan_num[i:i+len(mem_list)],base=2)|mem_num)+1 # O(m) => ๋ฐฐ์ด ์ฐ์ฐ์
if tmp==exact_num:
tmp_res+=1
result.append(tmp_res)
for obj in result:
print(obj)
์ฒซ๋ฒ์งธ๋
์ ๋ ฅ๋ฐ์ ๋ฌธ์์ด => ๋ฆฌ์คํธ => ์ซ์ ๋ฆฌ์คํธ => str => int(10์ง์)
๋๋ฒ์งธ๋
10์ง์๊ฐ ๋ ๋ ์๋ฅผ & ์ฐ์ฐ => +1 => 2์ ์ ๊ณฑ์์ธ์ง ํ์ธ (n&(n-1)์ด 0์ด๋ฉด 2์ ์ ๊ณฑ์)
python์ ๊ธฐ๋ณธ์ฐ์ฐ์ ์๊ฐ๋ณต์ก๋
์ด ๋ธ๋ก๊ทธ์ ๊ธฐ์ฌ๋ ๋ฐ์ ๋ฐ๋ฅด๋ฉด l[a:b]์ ๊ฐ์ด list์์ ์ผ๋ถ ๊ตฌ๊ฐ์ ์๋ผ ๋ณต์ฌํด์ค๋ ์ฐ์ฐ์ O(b-a)์ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๋ฏ๋ก, O(n-m)์ for๋ฌธ ์์์ O(m)์ ๋ฐฐ์ด ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ฉด O(nm-m^2)์ด ๋์ด ์๊ฐ ์ด๊ณผ๊ฐ ๋์จ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด์ฐจํผ ์ ๋ ๊ฒ ๊ณ์ฐํด๋ ๋ฐฐ์ด์ ๊ธธ์ด๊ฐ 20๋ง๊ฐ ์ด๊ธฐ ๋๋ฌธ์ ์ซ์์ ๋ฒ์๊ฐ ์ด๋ค ์๋ฃํ์ผ๋ก๋ 2์ 20๋ง์น๊น์ง ๋์ค๋ฏ๋ก ์ ์ฅํ ์๊ฐ ์๋ค. ๋ฐ๋ผ์ ๋ฌธ์์ด ๊ทธ๋๋ก ์ด์ฉํด์ผํ๋ค.
์ฑ ํด๋ต
์ฑ ์์์ ๊ฐ์ด ๋นํธ ์ฐ์ฐ์๊ฐ ์๋ ๊ณฑ์ ์ผ๋ก ์ ๊ทผํ์ด์ผ for๋ฌธ์ ์ด์ฉํ ํ์์์ด ํ ๋ฒ์ ๊ณ์ฐ์ ํ ์ ์๊ณ
: O(n-m) => O(1)
๊ณฑ์ ์ผ๋ก ์ ๊ทผํ์ด๋ ์นด๋ผ์ธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํ์ง ์์ผ๋ฉด O(nm)์ผ๋ก ์๊ฐ์ด๊ณผ๊ฐ ๋ฌ์ ๊ฒ์ด๋ค.
๊ฒฐ๊ตญ ์นด๋ผ์ธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํ ๊ณฑ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผํ๋ค.
๊ณฑ์ ์ ๋ค์๊ณผ ๊ฐ์ด ์งํ๋๋ค.
์นด๋ผ์ธ ๋ฐ ๊ตฌํํด๋ณด๊ธฐ
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <chrono>
using namespace std;
void printVector(vector<int>&v1) {
vector<int>::iterator iter;
for (iter = v1.begin(); iter != v1.end(); iter++) {
cout << *iter << " ";
}
cout << endl;
}
void normalize(vector<int> &num) {//num[]์ ์๋ฆฟ์ ์ฌ๋ฆผ์ ์ฒ๋ฆฌํ๋ค
num.push_back(0);
//์๋ฆฟ์ ์ฌ๋ฆผ์ ์ฒ๋ฆฌํ๋ค
for (int i = 0; i < num.size() - 1; i++) //num.size()-1 ์ค์
{
if (num[i] < 0)
{
int borrow = (abs(num[i]) + 9) / 10;
num[i + 1] -= borrow;
num[i] += borrow * 10;
}
else
{
num[i + 1] += num[i] / 10;
num[i] %= 10;
}
}
while (num.size() > 1 && num.back() == 0)
num.pop_back();
}
//๋ ๊ธด ์์ฐ์์ ๊ณฑ์ ๋ฐํํ๋ค
//๊ฐ ๋ฐฐ์ด์๋ ๊ฐ ์์ ์๋ฆฟ์๊ฐ 1์ ์๋ฆฌ์์๋ถํฐ ์์ํด ์ ์ฅ๋์ด ์๋ค.
//์:multiply([3,2,1], [6,5,4])=123*456=56088=[8, 8, 0, 6, 5]
vector<int> multiply(const vector<int> &a, const vector<int> &b)
{
vector<int> c(a.size() + b.size() + 1, 0);
for (int i = 0; i < a.size(); i++)
for (int j = 0; j < b.size(); j++)
c[i + j] += (a[i] * b[j]);
normalize(c);
return c;
}
//a+=b*(10^k)๋ฅผ ๊ตฌํํ๋ค
void addTo(vector<int> &a, const vector<int> &b, int k)
{
int length = b.size();
a.resize(max(a.size() + 1, b.size() + k));
for (int i = 0; i< length; i++)
a[i + k] += b[i]; //์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๊ตณ์ด ๋ค๋ฅธ vector๋ฅผ ์ ์ธํ์ง ์์๋ ๋๊ณ ๊ฐํธํด์ก๋ค
//์ ๊ทํ (+๋ง)
for (int i = 0; i < a.size(); i++)
{
if (a[i] >= 10)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
}
}
//a-=b;๋ฅผ ๊ตฌํํ๋ค a>=b๋ฅผ ๊ฐ์ ํ๋ค
void subFrom(vector<int> &a, const vector<int> &b)
{
int length = b.size();
a.resize(max(a.size() + 1, b.size()) + 1);
for (int i = 0; i< length; i++)
a[i] -= b[i];
//์ ๊ทํ
for (int i = 0; i < a.size(); i++)
{
if (a[i] < 0)
{
a[i] += 10;
a[i + 1] -= 1;
}
}
}
//๋ ๊ธด ์ ์์ ๊ณฑ์ ๋ฐํํ๋ค
//(a0+a1)*(b0+b1)=(a0*b0)(=z0)+(a1*b0+a0*b1)(=z1)+(a1*b1)(=z2)์ ์๋ฆฌ
vector<int> karatsuba(const vector<int> &a, const vector<int> &b)
{
int an = a.size(), bn = b.size();
//a๊ฐ b๋ณด๋ค ์งง์ ๊ฒฝ์ฐ ๋์ ๋ฐ๊พผ๋ค
if (an < bn)
return karatsuba(b, a);
//๊ธฐ์ ์ฌ๋ก:a๋ b๊ฐ ๋น์ด์๋ ๊ฒฝ์ฐ
if (an == 0 || bn == 0)
return vector<int>();
//๊ธฐ์ ์ฌ๋ก:a๊ฐ ๋น๊ต์ ์งง์ ๊ฒฝ์ฐ O(n^2) ๊ณฑ์
์ผ๋ก ๋ณ๊ฒฝํ๋ค
if (an <= 5)
return multiply(a, b);
int half = an / 2;
//a์ b๋ฅผ ๋ฐ์์ half์๋ฆฌ์ ๋๋จธ์ง๋ก ๋ถ๋ฆฌํ๋ค
vector<int> a0(a.begin(), a.begin() + half);
vector<int> a1(a.begin() + half, a.end());
vector<int> b0(b.begin(), b.begin() + min<int>(b.size(), half));
vector<int> b1(b.begin() + min<int>(b.size(), half), b.end());
//z2=a1*b1
vector<int> z2 = karatsuba(a1, b1);
//z0=a0*b0
vector<int> z0 = karatsuba(a0, b0);
//a0=a0+a1
//b0=b0+b1
addTo(a0, a1, 0);
addTo(b0, b1, 0);
//z1=(a0+a1)*(b0+b1)-z0-z2
vector<int> z1 = karatsuba(a0, b0);
subFrom(z1, z0);
subFrom(z1, z2);
//result=z0+z1*10^half+z2*10^(half*2)
vector<int> result;
addTo(result, z0, 0);
addTo(result, z1, half);
addTo(result, z2, half + half);
return result;
}
int main(void)
{
int c;
cin >> c;
cin.ignore(256, '\n');
vector<int> answer;
vector<int>::iterator iter;
vector<int> result;
for (int i = 0; i < c; i++) {
result.clear();
answer.push_back(0);
// string์ผ๋ก ๋ฐ์์ intํ ๋ฐฐ์ด๋ก ๋ณํ
string mem_list;
string fan_list;
getline(cin, mem_list);
getline(cin, fan_list);
int M = mem_list.size();
int F = fan_list.size();
vector<int> arr_m(M), arr_f(F);
for (int j = 0; j < M; j++) { // 200,000
// M์ด๋ฉด 1, F์ด๋ฉด 0
arr_m[j] = (mem_list[j] == 'M');
}
for (int j = 0; j < F; j++) { // 200,000
// F๋ ๋ฐ๋๋ก ์ ์ฅ
arr_f[j] = (fan_list[F - j - 1] == 'M');
}
vector<int> tmp_vector = multiply(arr_m, arr_f);
result = karatsuba(arr_m, arr_f); // karatsuba ์คํ
result.resize(M + F - 1);
result.resize(result.size()-M+1);
int k = 0;
for (int j = result.size()-1; k<=F-M; --j) {
k++;
if (result[j] == 0)
++answer[i];
}
}
for (iter = answer.begin(); iter != answer.end(); iter++) {
cout << *iter << endl;
}
return 0;
}
https://jaimemin.tistory.com/308 ์ด ๋ธ๋ก๊ทธ์ ์นด๋ผ์ธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์์ฉํ์ฌ ๋ฌธ์ ์ ๋ง๊ฒ ๋ณํํด๋ณด์๋ค. ์ฌ์ค ์นด๋ผ์ธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์๊ณ ๋ฆฌ์ฆ ์ํ ๋น์์ ๊ตฌํํ๋ ค๋ฉด ์๊ฐ์ด ๋๋ฌด ์ค๋๊ฑธ๋ฆด ๊ฒ ๊ฐ๋ค. (์นด๋ผ์ธ ๋ฐ๋ฅผ ๊ตฌํํด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์๊น..? ใ ) ๋ฐ๋ผ์ ์ค์ ์์ ์ฐ๊ธฐ ์ํด์ ํฐ ์๋ฅผ ๊ณฑํ๋ O(n^log3)์ ์๊ณ ๋ฆฌ์ฆ์ด ์๋ค๋ ๊ฒ, ๊ทธ๊ฒ ์นด๋ผ์ธ ๋ฐ ์๊ณ ๋ฆฌ์ฆ ์ด๋ผ๋ ๊ฒ์ ์์๋๊ธฐ๋ง ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๊ทธ๋๋ c++ ๋ฌธ๋ฒ ๊ณต๋ถํ๋ ์์ค์ ์นด๋ผ์ธ ๋ฐ๋ฅผ ๊ตฌํํ๊ฒ ๋์ด์ ๋ฌธ๋ฒ ๊ณต๋ถ์ ๋์์ด ๋ง์ด ๋ ๋ฏํ๋ค.
*์๊ณ ์คํ์ ๋ฌธ์ ์ง๋ง c์ธ์ด๋ก ํ์ด์ ์ ๋ต์ธ ์ฌ๋ ์ธ์ ์ ๋ต์ธ ์ฌ๋์ด ์๋ ๋ฏํ๋ค. ์ฑ์ ์ค๋ฅ์ธ๋ฏ ใ ใ *
Comment