Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // #pragma comment(linker, "/stack:200000000")
- #pragma GCC optimize("Ofast")
- // #pragma GCC option("arch=native","tune=native","no-zero-upper")
- // #pragma GCC target("avx")
- #include <iostream>
- #include <vector>
- #include <set>
- #include <algorithm>
- #include <ctime>
- #include <cmath>
- #include <map>
- #include <assert.h>
- #include <fstream>
- #include <cstdlib>
- #include <random>
- #include <iomanip>
- #include <cstring>
- #include <queue>
- using namespace std;
- #define sqr(a) ((a)*(a))
- #define all(a) (a).begin(), (a).end()
- const long long MOD = (long long) 1e9 + 7;
- const long long MAX_N = (long long) 100;
- long long binPow(long long a, long long b) {
- if (b == 0)
- return 1;
- long long ans = binPow(a, b / 2);
- ans = ans * ans % MOD;
- if (b % 2)
- ans = ans * a % MOD;
- return ans;
- }
- // const int maxn = 5e3 + 5;
- const int inf = 2e9 + 500;
- int dp[(1 << 17) + 100];
- bool used[(1 << 17) + 100];
- int s1, s2;
- void trans(int m1, int m2, int& newm, int& newc) {
- s1 = 31 - __builtin_clz(m1);
- s2 = 31 - __builtin_clz(m2);
- if (s1 < s2) {
- int dif = s2 - s1;
- assert(m1 == (m2 >> dif));
- newm = m2 & ((1 << dif) - 1);
- newm |= 1 << dif;
- newc = dif;
- } else {
- int dif = s1 - s2;
- assert(m2 == (m1 >> dif));
- newm = m1 & ((1 << dif) - 1);
- newm |= 1 << dif;
- newc = 0;
- }
- }
- const int maxc = 3e6;
- vector<int> q[maxc];
- int main() {
- freopen("input.txt", "r", stdin);
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- // srand(time(0));
- int n;
- cin >> n;
- vector<string> w(n);
- vector<int> msk(n, 0);
- for (int i = 0; i < n; i++) {
- cin >> w[i];
- }
- sort(all(w));
- for (int i = 0; i < n; i++) {
- msk[i] = 1;
- for (int j = 0; j < w[i].size(); j++) {
- msk[i] *= 2;
- msk[i] += w[i][j] - '0';
- }
- }
- for (int i = 0; i < (1 << 17); i++) {
- dp[i] = inf;
- }
- for (int i = 0; i < n; i++) {
- string word;
- {
- int m2 = msk[i];
- while (m2 > 1) {
- word += char(m2 % 2 + '0');
- m2 /= 2;
- }
- reverse(all(word));
- }
- int l = lower_bound(all(w), word) - w.begin();
- word += char('1' + 1);
- int r = upper_bound(all(w), word) - w.begin();
- word.pop_back();
- for (int j = l; j < r; j++) {
- if (j != i) {
- int start, _;
- trans(msk[i], msk[j], start, _);
- dp[start] = min(dp[start], max(s1, s2));
- }
- }
- }
- for (int i = 0; i < (1 << 17); i++) {
- if (dp[i] != inf) {
- q[dp[i]].push_back(i);
- }
- }
- int ans = inf;
- for (int p = 0; p < maxc; p++) {
- for (int iter = 0; iter < q[p].size(); iter++) {
- int m = q[p][iter];
- if (dp[m] != p) {
- continue;
- }
- string word;
- {
- int m2 = m;
- while (m2 > 1) {
- word += char(m2 % 2 + '0');
- m2 /= 2;
- }
- reverse(all(word));
- }
- int l = lower_bound(all(w), word) - w.begin();
- word += char('1' + 1);
- int r = upper_bound(all(w), word) - w.begin();
- word.pop_back();
- for (int i = l; i < r; i++) {
- int newm, newc;
- trans(m, msk[i], newm, newc);
- int val = dp[m] + newc;
- assert(val<maxc);
- if (newm == 1) {
- ans = min(ans, val);
- } else {
- if (dp[newm] > val) {
- // cout << newm << ' ' << val << endl;
- dp[newm] = val;
- q[val].push_back(newm);
- }
- }
- }
- {
- int m2 = m;
- while (m2 > 1) {
- int i = lower_bound(all(msk), m2) - msk.begin();
- if (i >= msk.size() || msk[i] != m2) {
- } else {
- int newm, newc;
- trans(m, msk[i], newm, newc);
- int val = dp[m] + newc;
- assert(val<maxc);
- if (newm == 1) {
- ans = min(ans, val);
- } else {
- if (dp[newm] > val) {
- // cout << newm << ' ' << val << endl;
- dp[newm] = val;
- q[val].push_back(newm);
- }
- }
- }
- m2 /= 2;
- }
- }
- }
- }
- if (ans == inf) {
- ans = 0;
- }
- cout << ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement