Submission #925928

#TimeUsernameProblemLanguageResultExecution timeMemory
925928chrislaiismeAlice, Bob, and Circuit (APIO23_abc)C++17
54 / 100
100 ms58684 KiB
#include "abc.h" #include<iostream> #include<algorithm> #include<string> #include<vector> #include<set> #include<math.h> using namespace std; // you may find the definitions useful const int OP_ZERO = 0; // f(OP_ZERO, x0, x1) = 0 const int OP_NOR = 1; // f(OP_NOR, x0, x1) = !(x0 || x1) const int OP_GREATER = 2; // f(OP_GREATER, x0, x1) = (x0 > x1) const int OP_NOT_X1 = 3; // f(OP_NOT_X1, x0, x1) = !x1 const int OP_LESS = 4; // f(OP_LESS, x0, x1) = (x0 < x1) const int OP_NOT_X0 = 5; // f(OP_NOT_X0, x0, x1) = !x0 const int OP_XOR = 6; // f(OP_XOR, x0, x1) = (x0 ^ x1) const int OP_NAND = 7; // f(OP_NAND, x0, x1) = !(x0 && x1) const int OP_AND = 8; // f(OP_AND, x0, x1) = (x0 && x1) const int OP_EQUAL = 9; // f(OP_EQUAL, x0, x1) = (x0 == x1) const int OP_X0 = 10; // f(OP_X0, x0, x1) = x0 const int OP_GEQ = 11; // f(OP_GEQ, x0, x1) = (x0 >= x1) const int OP_X1 = 12; // f(OP_X1, x0, x1) = x1 const int OP_LEQ = 13; // f(OP_LEQ, x0, x1) = (x0 <= x1) const int OP_OR = 14; // f(OP_OR, x0, x1) = (x0 || x1) const int OP_ONE = 15; // f(OP_ONE, x0, x1) = 1 const int NUM_LEN = 16; #define FOR(i) for(int i=0; i<NUM_LEN; i++) struct stc { string str; int num; stc(string S="", int n=0): str(S), num(n) {} }; bool operator<(stc a, stc b) { return a.str < b.str; } // Alice int // returns la alice( /* in */ const int n, /* in */ const char names[][5], /* in */ const unsigned short numbers[], /* out */ bool outputs_alice[] ) { int cur=0; // =============== Order to pos =============== ///// cout << endl; vector<string> vec, vec2; for(int i=0; i<n; i++) vec.push_back(names[i]); vec2 = vec; sort(vec.begin(), vec.end()); for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { bool bln = (vec[i] == vec2[j]); outputs_alice[cur++] = bln; ///// cout << bln << ' '; } ///// cout << endl; } ///// cout << endl; // =============== Ordered numbers =============== stc arr[n]; for(int i=0; i<n; i++) arr[i] = stc(names[i], numbers[i]); sort(arr, arr+n); for(int i=0; i<n; i++) { ///// cout << arr[i].num << ' '; FOR(j) { outputs_alice[cur++] = (arr[i].num >> j) & 1; } } ///// cout << endl; return cur; } // Bob int // returns lb bob( /* in */ const int m, /* in */ const char senders[][5], /* in */ const char recipients[][5], /* out */ bool outputs_bob[] ) { int cur=0; set<string> st; for(int i=0; i<m; i++) st.insert(senders[i]); for(int i=0; i<m; i++) st.insert(recipients[i]); int a[m], b[m]; for(int i=0; i<m; i++) a[i] = distance(st.begin(), st.lower_bound(senders[i])); for(int i=0; i<m; i++) b[i] = distance(st.begin(), st.lower_bound(recipients[i])); ///// for(int i=0; i<m; i++) cout << a[i] << "->" << b[i] << endl; ///// cout << endl; int n = st.size(); bool mat[n][n]; for(int i=0; i<n; i++) for(int j=0; j<n; j++) mat[i][j]=0; for(int i=0; i<m; i++) mat[a[i]][b[i]]=1; for(int i=0; i<n; i++) for(int j=0; j<n; j++) outputs_bob[cur++] = mat[i][j]; /*/// for(int i=0; i<n; i++) { for(int j=0; j<n; j++) cout << mat[i][j] << ' '; cout << endl; } cout << endl; ///*/ return cur; } // Circuit int // returns l circuit( /* in */ const int la, /* in */ const int lb, /* out */ int operations[], /* out */ int operands[][2], /* out */ int outputs_circuit[][16] ) { int cur = la + lb; // =============== Add operations =============== auto op = [&](int o, int a, int b) { operations[cur] = o; operands[cur][0] = a, operands[cur][1] = b; return cur ++ ; }; // =============== Zeroes =============== int zero = op(OP_ZERO, 0, 0); int ZERO = cur; FOR(i) op(OP_ZERO, 0, 0); // =============== Addition ============== auto ADD = [&](int a, int b) { vector<int> carry = {zero}, digit; FOR(i) { int d = op(OP_XOR, a+i, b+i); int c1 = op(OP_AND, a+i, b+i); int c2 = op(OP_AND, d, carry[i]); if(i != NUM_LEN-1) carry.push_back(op(OP_OR, c1, c2)); digit.push_back(d); } int ret = cur; FOR(i) op(OP_XOR, digit[i], carry[i]); return ret; }; // ================ Solve =============== int n = sqrt(lb), mat1=0, numbers=n*n, mat2=la; ///// cout << n << ' ' << mat1 << ' ' << numbers << ' ' << mat2 << "???" << endl; int ans[n]; for(int i=0; i<n; i++) ans[i] = ZERO; for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { int pos1 = mat2 + i*n+j; for(int k=0; k<n; k++) { int pos2= mat1 + j*n+k; int res = op(OP_AND, pos1, pos2); int num = cur; FOR(l) op(OP_AND, numbers + NUM_LEN*i+l, res); int new_ans = ADD(ans[k], num); ans[k] = new_ans; } } } for(int i=0; i<n; i++) { FOR(j) outputs_circuit[i][j] = ans[i]+j; } return cur; } /* 3 5 a 1 b 2 c 3 a -> c b -> c b -> a c -> c c -> c 1 0 0 0 1 0 0 0 1 . . . 0 0 1 1 0 1 0 0 1 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...