QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#121453#5874. Mystery Squarewhatever10 67ms3432kbC++172.4kb2023-07-08 09:52:282023-07-08 09:52:31

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-08 09:52:31]
  • 评测
  • 测评结果:10
  • 用时:67ms
  • 内存:3432kb
  • [2023-07-08 09:52:28]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
int rng(int l, int r) { return rnd() % (r - l + 1) + l; }
#define rep(i, a, b) for (int i = (a), I = (b); i <= I; ++i)
#define per(i, a, b) for (int i = (a), I = (b); i >= I; --i)
using i64 = long long;
using i128 = __int128_t;
template<typename T> void up(T &x, T y) { if (x < y) x = y; }
template<typename T> void down(T &x, T y) { if (x > y) x = y; }

string s;
int n, m;
i128 ans;
i128 msk0, msk1, all;

bool match(int x, int y) {
    return s[x] == '?' || s[x] == '0' + y;
}
void check(i128 x) {
    x *= x;
    if ((x & msk0) || ((all ^ x) & msk1)) return;
    ans = x;
}
i128 get_sqr(i128 x) {
    return sqrt((long double) x);
}

void dfs(int pos, i128 cur) {
    if (~ans) return;
    if (pos == m - 1) {
        i128 p = get_sqr(cur);
        while (p * p < cur) ++p;
        while (((p * p) >> m) == (cur >> m)) check(p), ++p;
        return;
    }
    if (match(pos, 0)) dfs(pos - 1, cur);
    if (match(pos, 1)) dfs(pos - 1, cur | i128(1) << pos);
}

void dfs(int pos, i128 cur, i128 sqr) {
    if (((sqr * sqr) ^ cur) & ((i128(1) << (pos - 1)) - 1)) return;
    if (~ans) return;
    if (pos == m) {
        check(sqr);
        check(sqr | i128(1) << (pos - 1));
        return;
    }
    int tmp = (sqr * sqr) >> pos & 1;
    rep(k, 0, 1) {
        int val = tmp + k * (sqr & 1);
        if (pos == 2) val += k;
        if (match(pos, val & 1)) dfs(pos + 1, cur | i128(val & 1) << pos, sqr | i128(k) << (pos - 1));
    }
}

void solve(int T) {
    cin >> s;
    n = s.size();
    reverse(s.begin(), s.end());
    m = (n + 1) / 2;
    int cnt_left = count(s.begin(), s.end() + m, '?');
    int cnt_right = count(s.begin() + m, s.end(), '?');
    ans = -1;
    msk0 = msk1 = all = 0;
    rep(i, 0, n - 1) {
        all |= i128(1) << i; 
        if (s[i] == '?') continue;
        (s[i] == '0' ? msk0 : msk1) |= i128(1) << i;
    }

    if (cnt_left < cnt_right) {
        if (match(0, 0)) dfs(2, 0, 0);
        if (match(0, 1)) dfs(2, 1, 1);
    } else {
        dfs(n - 1, 0);
    }
    cout << "Case #" << T << ": ";
    per(i, n - 1, 0) cout << int(ans >> i & 1);
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);

    int T;
    cin >> T;
    rep(t, 1, T) solve(t);

    return 0;
}

详细

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 67ms
memory: 3432kb

input:

25
1???
1
10??110??00??1000??
1??010?0110?1010?0?010?0111011?11100?100010?0??0??1
1??11????00??1?1?0?1??01??110110?11?00100110?00100?0?00
11?1?1???11111?11?1??11110000?00?????00??0?000?000?1
10??000000?0?00000?00000000??0?0000???00??????0000???
101???11??11000?????1??1?1??10??0?0100011?0001?01011001...

output:

Case #1: 1001
Case #2: 1
Case #3: 1011110110000100001
Case #4: 111010001100101000001010111011011100110001000110001
Case #5: 1101111110000101100101010111011001110010011000010000100
Case #6: 1111111111111111111111111000000000000000000000000001
Case #7: 1000000000000000000000000000000000000000000000000...

result:

ok 25 lines

Subtask #2:

score: 0
Time Limit Exceeded

Test #2:

score: 0
Time Limit Exceeded

input:

25
1????????????????????111101010000011100110101111000001011111100110000011000101100000010010110100101000????????????????????
10?11100?000111??11?01010110100??1?100111?001000000??0101?110?0111?011?11?1??00010111?010??100?100??10?010?001001110111110?1
1000100111100100110011010111100001111010?????????...

output:


result: