This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
typedef long long llong;
const int MAXN = 1000000 + 10;
const int INF = 1e9;
int n;
char a[MAXN];
char b[MAXN];
int add[16][16];
int rem[16][16];
int getBit[2][16];
int dp[MAXN][16];
bool bl[MAXN][16];
const std::vector <int> statePerms[] =
{
{},
{1},
{2},
{3},
{1, 2},
{1, 3},
{2, 3},
{2, 1},
{3, 1},
{3, 2},
{1, 2, 3},
{1, 3, 2},
{2, 1, 3},
{2, 3, 1},
{3, 1, 2},
{3, 2, 1}
};
int f(int idx, int state)
{
if (idx == n + 1)
{
return 0;
}
if (bl[idx][state])
{
return dp[idx][state];
}
bl[idx][state] = true;
dp[idx][state] = f(idx + 1, state) + (getBit[a[idx] - '0'][state] != b[idx] - '0');
for (int newMask = 0 ; newMask < 16 ; ++newMask)
{
if (add[state][newMask] == INF || getBit[a[idx] - '0'][newMask] != b[idx] - '0')
{
continue;
}
dp[idx][state] = std::min(dp[idx][state], add[state][newMask] + f(idx + 1, newMask));
}
for (int newMask = 0 ; newMask < 16 ; ++newMask)
{
if (rem[state][newMask] != INF)
{
dp[idx][state] = std::min(dp[idx][state], (getBit[a[idx] - '0'][state] != b[idx] - '0') + f(idx + 1, newMask));
}
}
return dp[idx][state];
}
bool contains(int idxOne, int idxTwo)
{
int ptrA = 0;
int ptrB = 0;
while (ptrA < statePerms[idxOne].size())
{
if (ptrB == statePerms[idxTwo].size())
{
return false;
}
if (statePerms[idxOne][ptrA] == statePerms[idxTwo][ptrB])
{
ptrA++;
}
ptrB++;
}
return true;
}
int getNewBit(int myBit, int myOp)
{
if (myOp == 1)
{
return 0;
}
if (myOp == 2)
{
return 1;
}
return myBit ^ 1;
}
void solve()
{
for (int bit = 0 ; bit < 2 ; ++bit)
{
for (int mask = 0 ; mask < 16 ; ++mask)
{
getBit[bit][mask] = bit;
for (const int &op : statePerms[mask])
{
getBit[bit][mask] = getNewBit(getBit[bit][mask], op);
}
}
}
for (int i = 0 ; i < 16 ; ++i)
{
for (int j = 0 ; j < 16 ; ++j)
{
add[i][j] = INF;
rem[i][j] = INF;
}
}
for (int maskOne = 0 ; maskOne < 16 ; ++maskOne)
{
for (int maskTwo = 0 ; maskTwo < 16 ; ++maskTwo)
{
if (maskOne == maskTwo || !contains(maskOne, maskTwo))
{
continue;
}
add[maskOne][maskTwo] = statePerms[maskTwo].size() - statePerms[maskOne].size();
rem[maskTwo][maskOne] = 0;
}
}
std::cout << f(1, 0) << '\n';
}
void input()
{
std::cin >> n;
std::cin >> a + 1;
std::cin >> b + 1;
}
void fastIOI()
{
std::ios_base :: sync_with_stdio(0);
std::cout.tie(nullptr);
std::cin.tie(nullptr);
}
int main()
{
fastIOI();
input();
solve();
return 0;
}
Compilation message (stderr)
lamp.cpp: In function 'bool contains(int, int)':
lamp.cpp:80:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
80 | while (ptrA < statePerms[idxOne].size())
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
lamp.cpp:82:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
82 | if (ptrB == statePerms[idxTwo].size())
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
lamp.cpp: In function 'void input()':
lamp.cpp:156:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
156 | std::cin >> a + 1;
| ~~^~~
lamp.cpp:157:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
157 | std::cin >> b + 1;
| ~~^~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |