1 solutions

  • 0
    @ 2024-8-28 23:28:55
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 20;
    
    int cnt[1 << N], a[1 << N], nums[N][N];
    char str[N][N];
    const int n = 16;
    
    int lowbit(int x) {
        return x & -x;
    }
    
    void file(int x, int y, int val) {
        for(int i = 0; i < n; i ++ ) {
            nums[x][i] &= ~(1 << val);
            nums[i][y] &= ~(1 << val);
        }
        int a = x / 4 * 4, b = y / 4 * 4;
        for(int i = 0; i < 4; i ++ ) 
            for(int j = 0; j < 4; j ++ ) 
                nums[a + i][b + j] &= ~(1 << val);
    }
    
    bool dfs(int now) {
        if(!now) return true;
        int pre[N][N];
        memcpy(pre, nums, sizeof pre);
        for(int i = 0; i < n; i ++ ) 
            for(int j = 0; j < n; j ++ ) 
                if(str[i][j] == '-') {
                    if(!nums[i][j]) return false;
                    if(cnt[nums[i][j]] == 1) {
                        str[i][j] = a[nums[i][j]] + 'A';
                        file(i, j, a[nums[i][j]]);
                        if(dfs(now - 1)) return true;
                        str[i][j] = '-';
                        memcpy(nums, pre, sizeof nums);
                        return false;
                    }
                }
        for(int i = 0; i < n; i ++ ) {
            int w[16] = {0}, val = 0; // val是用来判定这一行是不是一个数都不可以填
            for(int j = 0; j < n; j ++ ) 
                if(str[i][j] == '-') {
                    val |= nums[i][j];
                    for(int k = nums[i][j]; k; k -= lowbit(k)) 
                        w[a[lowbit(k)]] ++ ;
                }
                else {
                    val |= (1 << (str[i][j] - 'A'));
                    w[a[1 << (str[i][j] - 'A')]] = -1;
                }
            if(val != (1 << n) - 1) return false;
            for(int k = 0; k < n; k ++ ) 
                if(w[k] == 1) {
                    for(int j = 0; j < 16; j ++ ) 
                        if(str[i][j] == '-' && ((nums[i][j] >> k) & 1)) {
                            str[i][j] = k + 'A';
                            file(i, j, k);
                            if(dfs(now - 1)) return true;
                            
                            str[i][j] = '-';
                            memcpy(nums, pre, sizeof nums);
                            return false;
                        }
                }
        }
        for(int j = 0; j < n; j ++ ) {
            int w[n] = {0}, val = 0; // val是用来判定这一行是不是一个数都不可以填
            memset(w, 0, sizeof w);
            for(int i = 0; i < n; i ++ ) 
                if(str[i][j] == '-') {
                    val |= nums[i][j];
                    for(int k = nums[i][j]; k; k -= lowbit(k)) 
                        w[a[lowbit(k)]] ++ ;
                }
                else {
                    val |= (1 << (str[i][j] - 'A'));
                    w[a[1 << (str[i][j] - 'A')]] = -1;
                }
            if(val != (1 << n) - 1) return false;
            for(int k = 0; k < n; k ++ ) 
                if(w[k] == 1) {
                    for(int i = 0; i < 16; i ++ ) 
                        if(str[i][j] == '-' && ((nums[i][j] >> k) & 1)) {
                            str[i][j] = k + 'A';
                            file(i, j, k);
                            if(dfs(now - 1)) return true;
                            str[i][j] = '-';
                            memcpy(nums, pre, sizeof nums);
                            return false;
                        }
                }
        }
        for(int i = 0; i < n; i += 4) {
            for(int j = 0; j < n; j += 4) {
                int w[16] = {0}, val = 0;
                memset(w, 0, sizeof w);
                    for(int p = 0; p < 4; p ++ ) 
                        for(int q = 0; q < 4; q ++ ) 
                            if(str[i + p][j + q] == '-') {
                                val |= nums[i + p][j + q];
                                for(int k = nums[i + p][j + q]; k; k -= lowbit(k)) 
                                    w[a[lowbit(k)]] ++ ;
                            }
                            else {
                                val |= (1 << (str[i + p][j + q] - 'A'));
                                w[a[1 << (str[i + p][j + q] - 'A')]] = -1;
                            }
                if(val != (1 << n) - 1) return false;
                for(int k = 0; k < n; k ++ ) 
                    if(w[k] == 1) {
                         for(int p = 0; p < 4; p ++ ) 
                            for(int q = 0; q < 4; q ++ ) 
                                if(str[i + p][j + q] == '-' && ((nums[i + p][j + q] >> k) & 1)) {
                                    str[i + p][j + q] = k + 'A';
                                    file(i + p, j + q, k);
                                    if(dfs(now - 1)) return true;
                                    str[i + p][j + q] = '-';
                                    memcpy(nums, pre, sizeof nums);
                                    return false;
                                }
                    }
            }
        }
        int tmp = 17, x, y;
        for(int i = 0; i < n; i ++ ) 
            for(int j = 0; j < n; j ++ ) 
                if(str[i][j] == '-' && cnt[nums[i][j]] < tmp) {
                    x = i, y = j;
                    tmp = cnt[nums[i][j]];
                }
        for(int i = nums[x][y]; i; i -= lowbit(i)) {
            int val = a[lowbit(i)];
            file(x, y, val);
            str[x][y] = val + 'A';
            if(dfs(now - 1)) return true;
            str[x][y] = '-';
            memcpy(nums, pre, sizeof nums);
        }
        return false;
    }
    
    void work() {
        for(int i = 1; i < n; i ++ ) scanf("%s", str[i]);
        for(int i = 0; i < n; i ++ ) 
            for(int j = 0; j < n; j ++ )   
                nums[i][j] = (1 << n) - 1;
        int now = 0;
        for(int i = 0; i < n; i ++ ) 
            for(int j = 0; j < n; j ++ ) 
                if(str[i][j] != '-') file(i, j, str[i][j] - 'A');
                else now ++ ;
        for(int i = 0; i < n; i ++ ) puts(str[i]);
        puts("");
    }
    
    int main() {
        for(int i = 0; i < n; i ++ ) a[1 << i] = i;
        cnt[0] = 0;
        for(int i = 1; i < (1 << n); i ++ ) 
            for(int j = i; j; j -= lowbit(j)) cnt[i] ++ ;
        while(cin >> str[0]) {
            work();
        }
        return 0;
    }
    
    • 1

    Information

    ID
    484
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    2
    Accepted
    1
    Uploaded By