QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#35783#4250. Marswe_wendysCompile Error//C++1411.7kb2022-06-19 15:59:242024-04-28 07:13:56

Judging History

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

  • [2024-04-28 07:13:56]
  • 管理员手动重测本题所有提交记录
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-02-03 23:06:35]
  • 评测
  • [2022-06-19 15:59:24]
  • 提交

answer

//http://qoj.ac/contest/948/problem/4250
//#pragma GCC optimize("O3")
//#pragma GCC optimization ("unroll-loops")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define pb push_back
#define ff first
#define ss second

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

const int INF = 1e9;
const ll LLINF = 1e18;
const int MOD = 1e9 + 7;

template<class K> using sset =  tree<K, null_type, less<K>, rb_tree_tag, tree_order_statistics_node_update>;

inline ll ceil0(ll a, ll b) {
    return a / b + ((a ^ b) > 0 && a % b);
}

void setIO() {
    ios_base::sync_with_stdio(0); cin.tie(0);
}

string setval(string s, int l, int r, int v){
    string ret = s;
    for(int i = l; i <= r; i++){
        if(i - l >= 30) ret[i] = '0';
        else ret[i] = '0' + (bool)(v & (1 << (i - l)));
    }
    return ret;
}

int findval(string s, int l, int r){
    int ret = 0;
    for(int i = l; i <= r; i++) ret += ((s[i] - '0') << (i - l));
    return ret;
}

bool vis[50][50];
int moves[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

void dfs(int x, int y){
    vis[x][y] = true;
    for(int i = 0; i < 4; i++){
        int nx = x + moves[i][0], ny = y + moves[i][1];
        if(nx >= 0 && ny >= 0 && !vis[nx][ny]){
            vis[nx][ny] = true;
            dfs(nx, ny);
        }
    }
}

int par[10000];

int find(int x){
    if(x == par[x]) return x;
    return par[x] = find(par[x]);
}

int enc(int x, int y){
    return x*50 + y;
}

string process(vector<vector<string>> arr, int x, int y, int t, int n){
    int lim = 2*(n - t - 1);
    //if its completely within the border then it doesnt mattter
    if(x < lim && y < lim) return arr[0][0]; 
    //on the corner
    if(x == lim && y == lim){
        int m = t*2 + 1;
        for(int i = 0; i <= enc(m + 1, m + 1); i++) par[i] = i;
        //base case
        if(t == 0){
            int cnt = 0;
            for(int i = 0; i < m + 2; i++){
                for(int j = 0; j < m + 2; j++){
                    cnt += arr[i][j][0] == '1';
                }
            }
            for(int i = 0; i < m + 2; i++){
                for(int j = 0; j < m + 2; j++){
                    for(int k = 0; k < 4; k++){
                        int ii = i + moves[k][0], jj = j + moves[k][1];
                        if(ii >= 0 && jj >= 0 && ii < m + 2 && jj < m + 2){
                            if(arr[i][j][0] == '1' && arr[ii][jj][0] == '1' && find(enc(ii, jj)) != find(enc(i, j))){
                                par[find(enc(ii, jj))] = find(enc(i, j));
                                cnt--;
                            }
                        }
                    }
                }
            }
            if(n == 1) return setval(arr[0][0], 0, 99, cnt);
            bool prv = false;
            vector<int> v;
            //right to left
            for(int i = 2; i >= 0; i--){
                if(arr[0][i][0] == '1' && !prv) v.pb(find(enc(0, i))), prv = true;
                if(arr[0][i][0] == '0') prv = false;
            }
            //top to bottom
            for(int i = 1; i <= 2; i++){
                if(arr[i][0][0] == '1' && !prv) v.pb(find(enc(i, 0))), prv = true;
                if(arr[i][0][0] == '0') prv = false;
            }
            bool in[v.size()];
            memset(in, false, sizeof(in));
            stack<int> s;
            string ret = "";
            for(int i = 0; i < 100; i++) ret += "0";
            //11, close open
            //10, close
            //01, open
            //00, sadge
            for(int i = 0; i < v.size(); i++){
                //close the interval
                if(!s.empty() && in[find(v[i])]){
                    while(find(v[s.top()]) != find(v[i])){
                        ret[s.top()*2 + 1] = '1';
                        s.pop();
                    }
                    s.pop();
                    s.push(i);
                }
                //open an interval
                else {
                    ret[i*2] = '1';
                    in[find(v[i])] = true;
                    s.push(i);
                }
            }
            while(s.size()){
                ret[s.top()*2 + 1] = '1';
                s.pop();
            }
            ret = setval(ret, 90, 99, cnt);
            return ret;
        }
        //construct the grid
        int grid[m + 2][m + 2];
        memset(grid, 0, sizeof(grid));
        //2x2 square
        for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) grid[i][j] = arr[i][j][0] - '0';
        //2xM and Mx2 rectangle
        for(int i = 0; i < m; i++){
            for(int j = 0; j < 2; j++){
                grid[j][i + 2] = arr[0][2][j*m + i] - '0';
                grid[i + 2][j] = arr[2][0][j*m + i] - '0';
            }
        }
        //top left border
        for(int i = 0; i < m; i++){
            grid[2][i + 2] = arr[1][2][m + i] - '0';
            grid[i + 2][2] = arr[2][1][m + i] - '0';
        }
        //merge all adjacent cells on outer border
        /*for(int i = 0; i < m + 2; i++){
            for(int j = 0; j < m + 2; j++){
                cout << grid[i][j] << " ";
            }
            cout << endl;
        }*/
        int cnt = findval(arr[2][2], 90, 99);
        for(int i = 0; i < m + 2; i++){
            for(int j = 0; j < 2; j++){
                cnt += grid[j][i];
                cnt += grid[i][j];
            }
        }
        //overcounts some grids
        cnt -= grid[0][0];
        cnt -= grid[0][1];
        cnt -= grid[1][0];
        cnt -= grid[1][1];
        for(int i = 0; i < m + 2; i++){
            if(grid[0][i] && grid[1][i] && find(enc(0, i)) != find(enc(1, i))){
                par[find(enc(0, i))] = find(enc(1, i));
                cnt--;
            }
            if(grid[i][0] && grid[i][1] && find(enc(i, 0)) != find(enc(i, 1))){
                par[find(enc(i, 0))] = find(enc(i, 1));
                cnt--;
            }
            for(int j = 0; j < 2; j++){
                if(i < m + 1 && grid[i][j] && grid[i + 1][j] && find(enc(i, j)) != find(enc(i + 1, j))){
                    par[find(enc(i, j))] = find(enc(i + 1, j));
                    cnt--;
                }
                if(i < m + 1 && grid[j][i] && grid[j][i + 1] && find(enc(j, i)) != find(enc(j, i + 1))){
                    par[find(enc(j, i))] = find(enc(j, i + 1));
                    cnt--;
                }
            }
        }
        //merge all adjacent cells on inner border
        for(int i = m; i >= 2; i--){
            if(grid[2][i] && grid[2][i + 1] && find(enc(2, i)) != find(enc(2, i + 1))){
                par[find(enc(2, i))] = find(enc(2, i + 1));
            }
        }
        for(int i = 3; i <= m + 1; i++){
            if(grid[i][2] && grid[i - 1][2] && find(enc(i, 2)) != find(enc(i - 1, 2))){
                par[find(enc(i, 2))] = find(enc(i - 1, 2));
            }
        }
        //decode the components of inner grid
        vector<int> vv;
        bool prv = false;
        //right to left
        for(int i = m + 1; i >= 2; i--){
            if(grid[2][i] && !prv) vv.pb(find(enc(0, i))), prv = true;
            if(!grid[2][i]) prv = false;
        }
        //top to bottom
        for(int i = 3; i <= m + 1; i++){
            if(grid[i][2] && !prv) vv.pb(find(enc(i, 0))), prv = true;
            if(!grid[i][2]) prv = false;
        }
        stack<int> s;
        int id[vv.size()];
        for(int i = 0; i < vv.size(); i++){
            //open an interval
            if(arr[2][2][2*i] == '1'){
                s.push(i);
            }
            id[i] = s.top();
            for(int j = 0; j < i; j++){
                if(id[j] == id[i]){
                    par[find(vv[j])] = find(vv[i]);
                }
            }
            //close an interval
            if(arr[2][2][2*i + 1] == '1'){
                s.pop();
            }
        }
        //merge edges between grids
        for(int i = 2; i < m + 2; i++){
            if(grid[1][i] && grid[2][i] && find(enc(1, i)) != find(enc(2, i))){
                par[find(enc(1, i))] = find(enc(2, i));
                cnt--;
            }
            if(grid[i][1] && grid[i][2] && find(enc(i, 1)) != find(enc(i, 2))){
                par[find(enc(i, 1))] = find(enc(i, 2));
                cnt--;
            }
        }
        //encode the components of the current grid
        prv = false;
        vector<int> v;
        //right to left
        for(int i = m + 1; i >= 0; i--){
            if(grid[0][i] && !prv) v.pb(enc(0, i)), prv = true;
            if(!grid[0][i]) prv = false;
        }
        //top to bottom
        for(int i = 1; i <= m + 1; i++){
            if(grid[i][0] && !prv) v.pb(enc(i, 0)), prv = true;
            if(!grid[i][0]) prv = false;
        }
        bool in[v.size()];
        memset(in, false, sizeof(in));
        assert(s.empty());
        string ret = "";
        for(int i = 0; i < 100; i++) ret += "0";
        if(t == n - 1){
            return setval(ret, 0, 100, cnt);
        }
        //i*2 - open, i*2 + 1 - close
        for(int i = 0; i < v.size(); i++){
            //close the interval
            if(!s.empty() && in[find(v[i])]){
                while(find(v[s.top()]) != find(v[i])){
                    ret[s.top()*2 + 1] = '1';
                    s.pop();
                }
                s.pop();
                s.push(i);
            }
            //open an interval
            else {
                ret[i*2] = '1';
                in[find(v[i])] = true;
                s.push(i);
            }
        }
        while(s.size()){
            ret[s.top()*2 + 1] = '1';
            s.pop();
        }
        ret = setval(ret, 90, 99, cnt);
        return ret;
    } else {
        //if its on the bottom border, needs to be rotated
        if(x == lim){
            for(int i = 0; i < 3; i++){
                for(int j = 0; j < i; j++){
                    swap(arr[i][j], arr[j][i]);
                }
            }
        }
        //if right border stores everything to the right and down two rows
        //0         2*t + 2
        //2*t + 3   4*t + 6
        //if bottom border stores everything down and to the right two rows
        //0         2*t + 3
        //2*t + 2   4*t + 6
        string ret = "";
        for(int i = 0; i < 2; i++){
            for(int j = 0; j < 2; j++){
                ret += arr[i][j][0];
            }
            for(int j = 0; j < 2*t + 1; j++) ret += arr[i][2][j];
        }
        while(ret.length() < 100) ret += "0";
        return ret;
    }
}

/*int main(){
    setIO();
    int n;
    cin >> n;
    char arr[2*n + 1][2*n + 1];
    string s[2*n + 1][2*n + 1];
    for(int i = 0; i <= 2*n; i++) for(int j = 0; j <= 2*n; j++){
        char x;
        cin >> x;
        s[i][j] += x;
        for(int k = 1; k < 100; k++) s[i][j] += "0";
    }
    for(int t = 0; t < n; t++){
        for(int i = 0; i <= 2*(n - t - 1); i++){
            for(int j = 0; j <= 2*(n - t - 1); j++){
                vector<vector<string>> arr(3, vector<string>(3));
                for(int x = 0; x < 3; x++){
                    for(int y = 0; y < 3; y++){
                        arr[x][y] = s[i + x][j + y];
                    }
                }
                s[i][j] = process(arr, i, j, t, n);
            }
        }
    }
    string ans = s[0][0];    
    assert(ans.length() == 100);
    cout << findval(ans, 0, 99) << endl;
}

Details

answer.code:332:1: error: unterminated comment
  332 | /*int main(){
      | ^