QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#90731#5250. Combination LocksDenisovWA 2ms3560kbC++238.3kb2023-03-25 01:02:142023-03-25 01:02:16

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-25 01:02:16]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:3560kb
  • [2023-03-25 01:02:14]
  • 提交

answer

//#pragma GCC optimize("Ofast", "unroll-loops")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4")

#ifdef __APPLE__
#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <cstdint>
#include <cstring>
#include <string>
#include <cstdlib>
#include <vector>
#include <bitset>
#include <map>
#include <queue>
#include <ctime>
#include <stack>
#include <set>
#include <list>
#include <random>
#include <deque>
#include <functional>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <complex>
#include <numeric>
#include <immintrin.h>
#include <cassert>
#include <array>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <thread>
#else
#include <bits/stdc++.h>
#endif

#define all(a) a.begin(),a.end()
#define len(a) (int)(a.size())
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define fi first
#define se second

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

template<typename T>
bool umin(T &a, T b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T>
bool umax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

#if __APPLE__
#define D for (bool _FLAG = true; _FLAG; _FLAG = false)
#define LOG(...) print(#__VA_ARGS__" ::", __VA_ARGS__) << endl
template <class ...Ts> auto &print(Ts ...ts) { return ((cerr << ts << " "), ...); }
#else
#define D while (false)
#define LOG(...)
#endif

const int max_n = -1, inf = 1000111222;

const int max_log=10;

template<typename Edge>
class GraphIterator {
public:
    class OutgoingEdges {
    public:
        OutgoingEdges(const GraphIterator *g, int l, int r): g(g), l(l), r(r) {
        }

        const Edge* begin() const {
            if (l == r) {
                return 0;
            }
            return &g->prepared_edges[l];
        }

        const Edge* end() const {
            if (l == r) {
                return 0;
            }
            return &g->prepared_edges[r];
        }

    private:
        int l, r;
        const GraphIterator *g;
    };

    void clear() {
        prepared_edges.clear();
        edges.clear();
        start.clear();
        prepared = false;
    }

    void add_edge(int from, const Edge &e) {
        assert(!prepared && from >= 0);
        edges.push_back({from, e});
    }

    void prepare() {
        assert(!prepared);
        int n = 0;
        for (const auto &e : edges) {
            n = max(n, e.first);
        }
        n += 2;
        start.resize(n);
        for (const auto &e : edges) {
            ++start[e.first + 1];
        }
        for (int i = 1; i < n; ++i) {
            start[i] += start[i - 1];
        }
        prepared_edges.resize(edges.size() + 1);
        auto counter = start;
        for (const auto &e : edges) {
            prepared_edges[counter[e.first]++] = e.second;
        }
        prepared = true;
    }

    OutgoingEdges operator [] (int from) const {
        assert(prepared);
        if (from < 0 || from + 1 >= start.size()) {
            return {this, 0, 0};
        }
        return {this, start[from], start[from + 1]};
    }

    OutgoingEdges out(int from, int shift) const {
        assert(prepared);
        if (from < 0 || from + 1 >= start.size() || start[from] + shift >= start[from + 1]) {
            return {this, 0, 0};
        }
        return {this, start[from] + shift, start[from + 1]};
    }

private:
    vector<Edge> prepared_edges;
    vector<pair<int, Edge>> edges;
    vector<int> start;
    bool prepared = false;
};

namespace max_flow {

    typedef int CapacityType;
    const CapacityType infCapacity = 1000111222;

    const int max_v = (1ll<<10)+10;

    struct edge {
        int to;
        CapacityType residual_capacity;

        edge(int to, CapacityType residual_capacity): to(to), residual_capacity(residual_capacity) {
        }
    };

    vector<edge> edges;
    GraphIterator<int> g;

    template<bool bidirectional = false>
    void add_edge(int u, int v, CapacityType capacity) {
        g.add_edge(u, edges.size());
        edges.push_back({v, capacity});
        g.add_edge(v, edges.size());
        edges.push_back({u, bidirectional ? capacity : 0});
    }

    int h[max_v], num[max_v];

    bool bfs(int s, int t) {
        memset(h, -1, sizeof(h[0]) * (t + 1));
        h[s] = 0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : g[v]) {
                if (edges[id].residual_capacity && h[edges[id].to] == -1) {
                    h[edges[id].to] = h[v] + 1;
                    q.push(edges[id].to);
                    if (edges[id].to == t) {
                        return true;
                    }
                }
            }
        }
        return h[t] != -1;
    }

    CapacityType dfs(int v, int t, CapacityType f) {
        if (v == t) {
            return f;
        }
        for (int id : g.out(v, num[v])) {
            if (edges[id].residual_capacity && h[v] + 1 == h[edges[id].to]) {
                CapacityType res = dfs(edges[id].to, t, min(f, edges[id].residual_capacity));
                if (res) {
                    edges[id].residual_capacity -= res;
                    edges[id ^ 1].residual_capacity += res;
                    return res;
                }
            }
            ++num[v];
        }
        return 0;
    }

    long long dinic(int s, int t) {
        g.prepare();
        long long res = 0;
        while (bfs(s, t)) {
            memset(num, 0, sizeof(num[0]) * (t + 1));
            while (CapacityType f = dfs(s, t, infCapacity)) {
                res += f;
            }
        }
        return res;
    }

    bool reachable[max_v];

    void dfs(int v) {
        reachable[v] = 1;
        for (int id : g[v]) {
            if (!reachable[edges[id].to] && edges[id].residual_capacity) {
                dfs(edges[id].to);
            }
        }
    }

/**
 * call after dinic(s, t)
 * res[v] = 1 for vertices in "s" set
 * res[v] = 0 for vertices in "t" set
**/
    vector<int> get_cut(int s, int t) {
        memset(reachable, 0, sizeof(reachable[0]) * (t + 1));
        dfs(s);
        return {reachable, reachable + t + 1};
    }

    void clr(int t) {
        edges.clear();
        g.clear();
    }

}

int n,c;
bool used[1ll<<max_log];
bool blocked[1ll<<max_log];

void dfs(int now)
{
    used[now]=1;
    for (int i=0;i<n;i++){
        if (!used[now^(1ll<<i)] && !blocked[now^(1ll<<i)]){
            dfs(now^(1ll<<i));
        }
    }
}

void solve()
{
    cin>>n>>c;
    string s,t;
    cin>>s>>t;
    int start=0;
    for (int i=0;i<n;i++){
        if (s[i]==t[i]){
            start+=(1ll<<i);
        }
    }
    memset(blocked,0,sizeof(blocked));
    for (int i=0;i<c;i++){
        string p;
        cin>>p;
        int mask=0;
        for (int j=0;j<n;j++){
            if (p[j]=='='){
                mask+=(1ll<<j);
            }
        }
        blocked[mask]=1;
    }
    memset(used,0,sizeof(used));
    dfs(start);
    int want=0;
    for (int i=0;i<(1ll<<n);i++){
        if (used[i] && __builtin_popcountll(i)%2==__builtin_popcountll(start)%2){
            max_flow::add_edge(1ll<<n,i,1);
            want++;
            for (int j=0;j<n;j++){
                if (used[i^(1ll<<j)]){
                    max_flow::add_edge(i,i^(1ll<<j),1);
                }
            }
        }
        if (used[i] && __builtin_popcountll(i)%2!=__builtin_popcountll(start)%2){
            max_flow::add_edge(i,(1ll<<n)+1,1);
        }
    }
    bool alice=want==max_flow::dinic(1ll<<n,(1ll<<n)+1);
    max_flow::clr((1ll<<n)+1);
    cout<<(alice ? "Alice" : "Bob")<<"\n";
}

int main() {
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int test;
    cin>>test;
    while (test--){
        solve();
    }
}

/*
3
2 2
12
89
=.
==
3 1
204
101
.==
3 2
000
000
...
==.
*/

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3344kb

input:

2
1 0
0
0
1 1
0
0
.

output:

Alice
Bob

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 0ms
memory: 3472kb

input:

8
2 0
00
00
2 1
00
00
..
2 1
00
00
=.
2 2
00
00
..
=.
2 1
00
00
.=
2 2
00
00
..
.=
2 2
00
00
=.
.=
2 3
00
00
..
=.
.=

output:

Alice
Alice
Bob
Alice
Bob
Alice
Bob
Bob

result:

ok 8 lines

Test #3:

score: 0
Accepted
time: 2ms
memory: 3556kb

input:

20
4 4
4714
5245
..=.
..==
.==.
==..
4 1
2697
1438
.=..
4 5
9255
0677
...=
..==
=..=
==.=
====
4 12
3292
7326
...=
..=.
..==
.=..
.=.=
.==.
=...
=..=
=.==
==..
==.=
====
4 9
8455
2536
...=
..==
.=..
.=.=
.==.
.===
=...
==..
===.
4 12
5755
1517
...=
..=.
..==
.=..
.=.=
.===
=..=
=.=.
=.==
==..
==.=
=...

output:

Alice
Bob
Alice
Bob
Bob
Alice
Bob
Bob
Alice
Alice
Bob
Alice
Alice
Bob
Bob
Bob
Bob
Bob
Bob
Bob

result:

ok 20 lines

Test #4:

score: 0
Accepted
time: 2ms
memory: 3560kb

input:

20
5 30
99942
90170
.....
....=
...==
..=..
..=.=
..==.
..===
.=...
.=..=
.=.=.
.=.==
.==..
.==.=
.===.
.====
=...=
=..=.
=..==
=.=..
=.=.=
=.==.
=.===
==...
==..=
==.=.
==.==
===..
===.=
====.
=====
5 14
11760
95480
...=.
...==
..=..
..=.=
.=...
.=..=
.====
=....
=...=
=.=..
=.==.
==...
==.==
=====...

output:

Bob
Alice
Alice
Alice
Alice
Bob
Bob
Bob
Alice
Alice
Alice
Bob
Alice
Alice
Alice
Alice
Alice
Alice
Alice
Bob

result:

ok 20 lines

Test #5:

score: -100
Wrong Answer
time: 2ms
memory: 3548kb

input:

20
6 62
188256
588825
......
.....=
....=.
....==
...=..
...=.=
...==.
...===
..=...
..=..=
..=.=.
..=.==
..==..
..==.=
..===.
..====
.=....
.=...=
.=..=.
.=..==
.=.=..
.=.=.=
.=.==.
.=.===
.==..=
.==.=.
.==.==
.===..
.===.=
.=====
=.....
=....=
=...=.
=...==
=..=..
=..=.=
=..==.
=..===
=.=...
=.=.....

output:

Bob
Bob
Alice
Alice
Alice
Bob
Bob
Bob
Bob
Alice
Bob
Bob
Alice
Alice
Bob
Bob
Alice
Alice
Alice
Bob

result:

wrong answer 15th lines differ - expected: 'Alice', found: 'Bob'