(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #981616

#TimeUsernameProblemLanguageResultExecution timeMemory
981616SirLemonMeringueAlice, Bob, and Circuit (APIO23_abc)C++17
66 / 100
77 ms17508 KiB
#include "abc.h" #include <bits/stdc++.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 // Alice int // returns la alice( /* in */ const int n, /* in */ const char names[][5], /* in */ const unsigned short numbers[], /* out */ bool outputs_alice[] ) { if (n==1){ //output numbers[0] for(int i=0;i<16;i++){ outputs_alice[i] = numbers[0] & (1<<i); } return 16; } else if (n<=30){ vector<string> stringss; map<string,int> order; for(int i=0;i<n;i++) { stringss.push_back(names[i]); order[names[i]] = i; } sort(stringss.begin(),stringss.end()); map<int, string> position; //the person at position map<int,int> nums; //the number of person at position for(int i=0;i<n;i++){ position[i] = stringss[i]; nums[i] = numbers[order[position[i]]]; } for(int j=0;j<n;j++){ //cout << position[j] << ": " << nums[j] << ", " << j << "\n"; for(int i=0;i<16;i++){ outputs_alice[21*j+i] = nums[j] & (1<<i); } int poss = order[position[j]]; for(int i=16;i<21;i++){ outputs_alice[21*j+i] = poss & (1<<(i-16)); } } return 21*n; } } // Bob int // returns lb bob( /* in */ const int m, /* in */ const char senders[][5], /* in */ const char recipients[][5], /* out */ bool outputs_bob[] ) { /* outputs_bob[0] = 1; outputs_bob[1] = 1; outputs_bob[2] = 0; */ //output m bool s1 = true; if (m>1){ for(int i=0;i<5;i++){ if (senders[0][i]!=senders[1][i]){ s1 = false; break; } } for(int i=0;i<5;i++){ if (recipients[0][i]!=recipients[1][i]){ s1 = false; break; } } } if (s1){ for(int i=0;i<10;i++){ outputs_bob[i] = m & (1<<i); } return 10; } else { set<string> stringss; for(int e=0;e<m;e++){ stringss.insert(senders[e]); stringss.insert(recipients[e]); } int n = (int)stringss.size(); int count = 0; map<string,int> poss; for(auto s : stringss){ poss[s] = count; count++; } for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ outputs_bob[n*i+j] = 0; } } //for all edges, mark at the receiving end for(int e=0;e<m;e++){ int s = poss[senders[e]]; int r = poss[recipients[e]]; //cout << senders[e] << " (" << poss[senders[e]] << ") -> " << recipients[e] << " (" << poss[recipients[e]] << ")\n"; outputs_bob[n*r+s] = 1; } return n*n; } } struct gate { int p; int x0,x1; }; vector<gate> bitShiftBlock(int pos, int shift, int left, int size, int determinant=-1){ //if determinant output = 0, block=0 vector<gate> block; //the first shift are all 0 for(int i=0;i<shift;i++){ block.push_back({0,0,1}); } //the remaining work from the left for(int i=0;i<size-shift;i++){ if (determinant==-1){ block.push_back({8,left+i,left+i}); } else block.push_back({8,left+i,determinant}); } return block; } //sum block //maybe some can be saved here // {block of length size starting at left}{block of length size starting at left2}{stuff.....sum of two blocks} vector<gate> sumBlock(int pos, int left, int left2, int size){ vector<gate> block; vector<gate> endBlock; //first gate is sum0: xor int at = pos; block.push_back({6,left,left2}); endBlock.push_back({10,at,0}); at++; //next gate is carry0: and block.push_back({8,left,left2}); at++; //create remaining using full adders for(int i=1;i<size;i++){ //D is xor of things block.push_back({6,left+i,left2+i}); at++; // D is at-1, Cin is at-2 //E is D AND Cin block.push_back({8,at-1,at-2}); at++; //E is at-1, D is at-2, Cin is at-3 //F is A AND B block.push_back({8,left+i,left2+i}); at++; //F is at-1, E is at-2, D is at-3, Cin is at-4 //S is D XOR Cin block.push_back({6,at-3,at-4}); endBlock.push_back({10,at,0}); at++; //F is at-2, E is at-3, D is at-4, Cin is at-5 //Cout is F XOR E block.push_back({6,at-2,at-3}); at++; } //add endBlock to block for(auto a : endBlock){ block.push_back(a); } return block; } //sort block //{block of length size starting at left1}{block of length size starting at left2}{stuff...2 blocks in order smallest to largest} vector<gate> sortBlock(int pos, int left1, int left2, int size){ vector<gate> block; stack<gate> smallBlock; stack<gate> bigBlock; int at = pos; block.push_back({0,0,1}); //Uin is initially zero block.push_back({0,0,1}); //L1in is initially zero at += 2; //Uin is at-2, L1in is at-1 for(int i=1;i<=size;i++){ //define B1 and B2 int B1 = left1+size-i; int B2 = left2+size-i; //define Uin and L1in int Uin = at-2; int L1in = at-1; block.push_back({8,B1,L1in}); int a = at++; block.push_back({2,B2,L1in}); int b = at++; block.push_back({14,a,b}); int c = at++; block.push_back({8,Uin,c}); int d = at++; block.push_back({8,B1,B2}); int e = at++; block.push_back({14,e,d}); int kk = at++; smallBlock.push({8,kk,kk}); block.push_back({14,B1,B2}); int f = at++; block.push_back({2,f,kk}); int g = at++; bigBlock.push({14,e,g}); block.push_back({6,B1,B2}); int h = at++; block.push_back({4,B1,B2}); int j = at++; block.push_back({4,Uin,j}); int k = at++; block.push_back({14,Uin,h}); at++; block.push_back({14,L1in,k}); at++; } while(!smallBlock.empty()){ block.push_back({smallBlock.top()}); smallBlock.pop(); } while(!bigBlock.empty()){ block.push_back({bigBlock.top()}); bigBlock.pop(); } return block; } // 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] ) { //first bits are input int L = la+lb; int n = la/21; if (L==26){ //start by adding null block of zeros for(int i=0;i<16;i++){ operations[L] = 0; operands[L][0] = 0; operands[L][1] = 0; L++; } //do all things for(int i=0;i<10;i++){ //add the bitshift block at L vector<gate> block = bitShiftBlock(L,i,0,16,16+i); for(auto a : block){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } //add the sum block at L vector<gate> block2 = sumBlock(L,L-32,L-16,16); for(auto a : block2){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } } //answer is just last 16 bits for(int j=0;j<16;j++){ outputs_circuit[0][j] = L-16+j; } } else { vector<int> resultsStarts; //solve person by person for(int p=0;p<n;p++){ //add null block of zeros for(int i=0;i<16;i++){ operations[L] = 0; operands[L][0] = 0; operands[L][1] = 0; L++; } //then, for every other person, copy over their number if they sent a thing to p (0 otherwise), and add to running total for(int q=0;q<n;q++){ //add the bitshift block at L vector<gate> block = bitShiftBlock(L,0,21*q,16,la+n*p+q); for(auto a : block){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } //keep running total //add the sum block at L vector<gate> block2 = sumBlock(L,L-32,L-16,16); for(auto a : block2){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } } //result for this person is last 16 bits //printf("%d\n",L-16); resultsStarts.push_back(L-16); /* for(int j=0;j<16;j++){ outputs_circuit[p][j] = L-16+j; } */ } //shift all results to end, including number from alice for(int i=0;i<n;i++){ vector<gate> block = bitShiftBlock(L,0,resultsStarts[i],16); for(auto a : block){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } vector<gate> block2 = bitShiftBlock(L,0,21*i+16,5); for(auto a : block2){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } } //complete N-1 Passes for(int pass=n-2;pass>=0;pass--){ for(int firstSwap = 0;firstSwap<=pass;firstSwap++){ //define start of previous int prevStart = L - 21*n; //create the block with the appropriate swapped version vector<gate> swappedBlock = sortBlock(L,prevStart+21*firstSwap,prevStart+21*(firstSwap+1),21); for(auto a : swappedBlock){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } int sortedStart = L-21*2; //create block to add all before swapped part vector<gate> b1 = bitShiftBlock(L,0,prevStart,21*firstSwap); for(auto a : b1){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } //create block to add swapped part vector<gate> b2 = bitShiftBlock(L,0,sortedStart,21*2); for(auto a : b2){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } //create block to add all after swapped part vector<gate> b3 = bitShiftBlock(L,0,prevStart+21*(firstSwap+2),21*(n-(firstSwap+2))); for(auto a : b3){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } } } /* */ //results are then sorted for(int p=0;p<n;p++){ for(int j=0;j<16;j++){ outputs_circuit[p][j] = L-21*n + 21*p + j; } } } //printf("%d\n",L); return L; /* //start by adding null block of zeros for(int i=0;i<16;i++){ operations[L] = 0; operands[L][0] = 0; operands[L][1] = 0; L++; } //do all things for(int i=0;i<10;i++){ //add the bitshift block at L vector<gate> block = bitShiftBlock(L,i,0,16,16+i); for(auto a : block){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } //add the sum block at L vector<gate> block2 = sumBlock(L,L-32,L-16,16); for(auto a : block2){ operations[L] = a.p; operands[L][0] = a.x0; operands[L][1] = a.x1; L++; } } //answer is just last 16 bits for(int j=0;j<16;j++){ outputs_circuit[0][j] = L-16+j; } */ //printf("%d\n",L); /* operations[5] = 8; operations[6] = 14; operands[5][0] = 0; operands[5][1] = 4; operands[6][0] = 2; operands[6][1] = 5; int final_results[] = {20000, 0, 24464}; for(int i = 0; i < 3; ++i) for(int j = 0; j < 16; ++j) outputs_circuit[i][j] = 5 + (final_results[i] >> j & 1); return 7; */ }

Compilation message (stderr)

abc.cpp: In function 'int alice(int, const char (*)[5], const short unsigned int*, bool*)':
abc.cpp:67:1: warning: control reaches end of non-void function [-Wreturn-type]
   67 | }
      | ^
#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...