169 lines
3.5 KiB
C++
169 lines
3.5 KiB
C++
/*
|
|
VIM: let b:cf5build="clang -std=c++14 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
|
|
VIM: let b:cf5run="{OUT}"
|
|
*/
|
|
#include <iostream>
|
|
#include <exception>
|
|
#include <chrono>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
/*
|
|
* Give a N*N square matrix, return an array of its anti-diagonals. Look at the
|
|
* example for more details.
|
|
*
|
|
* Example:
|
|
* Input:
|
|
* 1 2 3
|
|
* 4 5 6
|
|
* 7 8 9
|
|
*
|
|
* Return the following :
|
|
* [
|
|
* [1],
|
|
* [2, 4],
|
|
* [3, 5, 7],
|
|
* [6, 8],
|
|
* [9]
|
|
* ]
|
|
*
|
|
* Input :
|
|
* 1 2
|
|
* 3 4
|
|
*
|
|
* Return the following :
|
|
* [
|
|
* [1],
|
|
* [2, 3],
|
|
* [4]
|
|
* ]
|
|
*/
|
|
|
|
std::vector<std::vector<int> > diagonal(const std::vector<std::vector<int> > &A)
|
|
{
|
|
size_t m = A.size();
|
|
size_t n = A.front().size();
|
|
|
|
std::vector<std::vector<int> > v(n+m-1);
|
|
|
|
int step = 0;
|
|
size_t k = 0;
|
|
for ( size_t i = 0; i < m; ++i, ++k ){
|
|
size_t c = std::min(i+1, n);
|
|
v[k].resize(c);
|
|
for ( size_t j = 0; j < c; ++j){
|
|
v[k][c-1-j] = A[i-j][j];
|
|
}
|
|
}
|
|
|
|
for ( size_t i = 1; i < n; ++i, ++k ){
|
|
size_t c = std::min(n-i, m);
|
|
v[k].resize(c);
|
|
for ( size_t j = 0; j < c; ++j){
|
|
v[k][c-1-j] = A[m-1-j][i+j];
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
std::vector<std::vector<int>> diagonal2(const std::vector<std::vector<int> > &A)
|
|
{
|
|
size_t m = A.size();
|
|
size_t n = A.front().size();
|
|
size_t mn_min = std::min(n,m);
|
|
size_t r_count = n+m-1;
|
|
|
|
std::vector<std::vector<int>> v(n+m-1);
|
|
|
|
for ( int i = 0; i < m; ++i ){
|
|
for ( int j = 0; j < n; ++j ){
|
|
size_t r = i+j;
|
|
|
|
auto q = i;
|
|
if ( r >= n ) {
|
|
q -= r-n+1;
|
|
}
|
|
|
|
if ( !v[r].size() ){
|
|
auto rr = std::min( r_count-r, r+1);
|
|
v[r].resize(std::min(rr,mn_min));
|
|
}
|
|
|
|
v[r][q] = A[i][j];
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
void print( const std::vector<std::vector<int>>& A )
|
|
{
|
|
return;
|
|
for ( const auto& a : A ){
|
|
for ( auto i : a ){
|
|
std::cout << i << ' ';
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
|
|
template <typename SOLUTION>
|
|
void test( SOLUTION s )
|
|
{
|
|
print( s( {
|
|
{ 1, 2, 3 },
|
|
{ 4, 5, 6 },
|
|
{ 7, 8, 9 }
|
|
} ) );
|
|
print( s( {
|
|
{ 1, 2, 3 },
|
|
{ 4, 5, 6 },
|
|
{ 7, 8, 9 },
|
|
{ 10, 11, 12 },
|
|
{ 13, 14, 15 },
|
|
{ 16, 17, 18 }
|
|
} ) );
|
|
print( s( {
|
|
{ 1, 2, 3, 4, 5 },
|
|
{ 6, 7, 8, 9, 10 },
|
|
{ 11, 12, 13, 14, 15 }
|
|
} ) );
|
|
}
|
|
|
|
int main ( void )
|
|
{try{
|
|
test(diagonal);
|
|
test(diagonal2);
|
|
|
|
auto begin = std::chrono::high_resolution_clock::now();
|
|
|
|
test(diagonal2);
|
|
|
|
auto mid = std::chrono::high_resolution_clock::now();
|
|
|
|
test(diagonal);
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
std::chrono::duration<double> seconds = end - begin;
|
|
std::chrono::duration<double> seconds1 = mid - begin;
|
|
std::chrono::duration<double> seconds2 = end - mid;
|
|
std::cout << "Time: " << seconds.count() << std::endl;
|
|
std::cout << "Time1: " << seconds1.count() << std::endl;
|
|
std::cout << "Time2: " << seconds2.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;
|
|
}}
|
|
|