Solution S o l u t i o n
可以枚举磁头的初始位置,计算出哪些地方是可以随便赋
0/1
0
/
1
的。
但这样一个初始序列可能会被多个磁头满足。就要用容斥去重。
ans=∑T⊆S(−1)|T|+12|P|P=⋂R⊆TR
a
n
s
=
∑
T
⊆
S
(
−
1
)
|
T
|
+
1
2
|
P
|
P
=
⋂
R
⊆
T
R
直接dfs,若
P=∅
P
=
∅
就退出搜索,这样复杂度是
O(n2n−−−√)
O
(
n
2
n
)
的。
// BEGIN CUT HERE
// END CUT HERE
#line 5 "MapGuessing.cpp"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 40;
string g, o;
int n, len;
ll a[N];
vector<ll> S;
class MapGuessing {
public:
inline void CalcA(int p) {
ll res = 0, S = 0;
string tmp = g;
int cnt = n, pos = p;
for (char c: o) {
if (isdigit(c)) {
cnt -= (tmp[p] == g[p]);
tmp[p] = c;
cnt += (tmp[p] == g[p]);
S |= 1ll << p;
if (cnt == n) res = S;
} else {
if (c == '<') --p; else ++p;
if (p < 0 || p >= n) return (void)(a[pos] = -1);
}
}
a[pos] = res;
}
inline int sgn(int d) {
return d & 1 ? 1 : -1;
}
inline int BitCount(ll S) {
int cnt = 0;
for (; S; S -= S & -S) ++cnt;
return cnt;
}
inline ll dfs(int i, int d, ll P) {
if (!P) {
if (i == S.size()) return sgn(d);
return 0;
}
if (i == S.size())
if (d) return sgn(d) * (1ll << BitCount(P));
else return 0;
return dfs(i + 1, d, P)
+ dfs(i + 1, d + 1, P & S[i]);
}
ll countPatterns(string goal, vector <string> code) {
g = goal; o.clear();
for (string t: code) o += t;
n = g.size(); len = o.size();
for (int i = 0; i < n; i++) {
CalcA(i);
if (~a[i]) S.push_back(a[i]);
}
return dfs(0, 0, (1ll << n) - 1);
}
// BEGIN CUT HERE
public:
void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); }
private:
template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { string Arg0 = "000"; string Arr1[] = {"0"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 4LL; verify_case(0, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_1() { string Arg0 = "001"; string Arr1[] = {"0>1"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 5LL; verify_case(1, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_2() { string Arg0 = "000"; string Arr1[] = {"1>1>1"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 1LL; verify_case(2, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_3() { string Arg0 = "11001"; string Arr1[] = {">><<<<><<"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 0LL; verify_case(3, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_4() { string Arg0 = "1000101011"; string Arr1[] = {"1<<0>>0>1"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 22LL; verify_case(4, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_5() { string Arg0 = "00000010000000000000000000000000"; string Arr1[] = {"><>>0<0<>>1>0><>", "<<0>>0<>><0>0>>><><", ">>>0<>", ">0><>>>>0<<><>>0>>>0<0>>0>"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 13601LL; verify_case(5, Arg2, countPatterns(Arg0, Arg1)); }
void test_case_6() { string Arg0 = "11100011010111111010100100110001101"; string Arr1[] = {"11111111111111111111"
,"1<><><><><><><><><>1"
,"1<>000>000><0<><0<>1"
,"1<0<><>0><0<00>00<>1"
,"1<>00<>000><0<0<0<>1"
,"1<><>0>0><0<0<><0<>1"
,"1<000<>0><0<0<><0<>1"
,"1<><><><><><><><><>1"
,"1<>000><000<>000><>1"
,"1<>0><><0<><>0><><>1"
,"1<>000><000<>000><>1"
,"1<><>0><><0<><>0><>1"
,"1<>000><000<>000><>1"
,"1<><><><><><><><><>1"
,"11111111111111111111"}; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 90LL; verify_case(6, Arg2, countPatterns(Arg0, Arg1)); }
// END CUT HERE
};
// BEGIN CUT HERE
int main(void) {
MapGuessing ___test;
___test.run_test(6);
system("pause");
}
// END CUT HERE