/* VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" VIM: let b:cf5run="{OUT}" VIM-: let b:cppflags=g:Iboost.g:Itbb VIM-: let b:ldflags=g:Lboost.g:Ltbb VIM-: let b:ldlibpath=g:Bboost.g:Btbb */ #include #include #include #include #include /* Median Stream You're given a list of n integers arr[0..(n-1)]. You must compute a list output[0..(n-1)] such that, for each index i (between 0 and n-1, inclusive), output[i] is equal to the median of the elements arr[0..i] (rounded down to the nearest integer). The median of a list of integers is defined as follows. If the integers were to be sorted, then: If there are an odd number of integers, then the median is equal to the middle integer in the sorted order. Otherwise, if there are an even number of integers, then the median is equal to the average of the two middle-most integers in the sorted order. Input n is in the range [1, 1,000,000]. Each value arr[i] is in the range [1, 1,000,000]. Output Return a list of n integers output[0..(n-1)], as described above. Example 1 n = 4 arr = [5, 15, 1, 3] output = [5, 10, 5, 4] The median of [5] is 5, the median of [5, 15] is (5 + 15) / 2 = 10, the median of [5, 15, 1] is 5, and the median of [5, 15, 1, 3] is (3 + 5) / 2 = 4. Example 2 n = 2 arr = [1, 2] output = [1, 1] The median of [1] is 1, the median of [1, 2] is (1 + 2) / 2 = 1.5 (which should be rounded down to 1). */ std::vector findMedian(std::vector arr) { // Write your code here std::vector r; std::vector l; for (size_t i = 0; i < arr.size(); ++i){ l.push_back(arr[i]); std::push_heap(l.begin(), l.end()); if (l.size() > ((i+1)/2+1)){ std::pop_heap(l.begin(), l.end()); l.resize(l.size()-1); } if ((i+1)%2){ r.push_back(l[0]); } else if (l.size() == 2){ r.push_back( (l[0]+l[1])/2 ); } else { r.push_back( (l[0]+std::max(l[1],l[2]))/2 ); } } return r; } // These are the tests we use to determine if the solution is correct. // You can add your own at the bottom, but they are otherwise not editable! void printIntegerVector(std::vector array) { int size = array.size(); std::cout << "["; for (int i = 0; i < size; i++) { if (i != 0) { std::cout << ", "; } std::cout << array[i]; } std::cout << "]"; } int test_case_number = 1; void check(std::vector & expected, std::vector & output) { int expected_size = expected.size(); int output_size = output.size(); bool result = true; if (expected_size != output_size) { result = false; } for (int i = 0; i < std::min(expected_size, output_size); i++) { result &= (output[i] == expected[i]); } const char* rightTick = "PASS - "; const char* wrongTick = "FAIL - "; if (result) { std::cout << rightTick << "Test #" << test_case_number << "\n"; } else { std::cout << wrongTick << "Test #" << test_case_number << ": Expected "; printIntegerVector(expected); std::cout << " Your output: "; printIntegerVector(output); std::cout << std::endl; } test_case_number++; } int main ( void ) {try{ auto begin = std::chrono::high_resolution_clock::now(); { std::vector arr_1{5, 15, 1, 3}; std::vector expected_1{5, 10, 5, 4}; std::vector output_1 = findMedian(arr_1); check(expected_1, output_1); }{ std::vector arr_2{2, 4, 7, 1, 5, 3}; std::vector expected_2{2, 3, 4, 3, 4, 3}; std::vector output_2 = findMedian(arr_2); check(expected_2, output_2); }{ std::vector arr_2{2, 4, 7, 1, 5}; std::vector expected_2{2, 3, 4, 3, 4}; std::vector output_2 = findMedian(arr_2); check(expected_2, output_2); }{ std::vector arr_2{2, 4, 7, 1, 5, 3, 4}; std::vector expected_2{2, 3, 4, 3, 4, 3, 4 }; std::vector output_2 = findMedian(arr_2); check(expected_2, output_2); } auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration seconds = end - begin; std::cout << "Time: " << seconds.count() << std::endl; return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}