Submission #1359795

#TimeUsernameProblemLanguageResultExecution timeMemory
1359795anangoVision Program (IOI19_vision)C++20
0 / 100
7 ms2564 KiB
#include "vision.h"
#include <bits/stdc++.h>
using namespace std;

void construct_network(int H, int W, int K) {
    //diagonal interactions
    vector<int> diag1_pre(H+W,-1); //the prefix OR of all cells with (r+c) < i
    vector<int> diag2_pre(H+W,-1); //the prefix OR of all cells with (r-c) + (W-1) < i
    vector<int> diag1_suf(H+W,-1); //the prefix OR of all cells with (r+c) >= i
    vector<int> diag2_suf(H+W,-1); //the prefix OR of all cells with (r-c) + (W-1) >= i
    //note 0<=r<H and 0<=c<W so r-c is between -(W-1) and (H-1)
    vector<vector<int>> diag1_indices(H+W-1);
    vector<vector<int>> diag2_indices(H+W-1);
    for (int r=0; r<H; r++) {
        for (int c=0; c<W; c++) {
            int diag1val = r+c;
            int diag2val = r-c + (W-1);
            //cerr << diag1val << " " << diag2val << " " << H << " " << W << r << " " << c << endl;
            int ID = r*W+c;
            diag1_indices[diag1val].push_back(ID);
            diag2_indices[diag2val].push_back(ID);
        }
    }
    for (int i=0; i<H+W-1; i++) {
        if (i>0) {
            //we literally do not care about efficiency
            diag1_pre[i+1] = add_or({diag1_pre[i], add_or(diag1_indices[i])});
            diag2_pre[i+1] = add_or({diag2_pre[i], add_or(diag2_indices[i])});
        }
        else {
            diag1_pre[i+1] = add_or(diag1_indices[i]);
            diag2_pre[i+1] = add_or(diag2_indices[i]);
        }
    }

    for (int i=H+W-2; i>=0; i--) {
        if (i<H+W-2) {
            //we literally do not care about efficiency
            diag1_suf[i] = add_or({diag1_suf[i+1], add_or(diag1_indices[i])});
            diag2_suf[i] = add_or({diag2_suf[i+1], add_or(diag2_indices[i])});
        }
        else {
            diag1_suf[i] = add_or(diag1_indices[i]);
            diag2_suf[i] = add_or(diag2_indices[i]);
        }
    }

    //we need to find if the distance is at least K
    //and then whether it's at least K+1
    auto check = [&](const int cut) {
        //adds instruction whether the distance is at least cut and returns the index
        //if either diagonal distance is at least cut, done
        vector<int> final_to_or;
        for (int i=1; i<H+W-1-cut; i++) {
            final_to_or.push_back(add_and({diag1_pre[i+1], diag1_suf[i+cut]}));
        }
        //cerr << final_to_or.size() << " " << cut << endl;
        return (final_to_or.size()==0? -1: add_or(final_to_or));
    };
    int a = check(K);
    int b = check(K+1);
    if (a!=-1 && b!=-1) {
        add_and({a, add_not(b)});
    }
    else if (a==-1) {
        add_and({0, add_not(0)}); //basically, add a zero
    }
    else if (b==-1) {
        add_not(add_not(a)); //ensure that a is the final instruction
    }


}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...