#include <iostream>
#include <fstream>
void m_qsort(int** m, int* cs, int M, int l, int r);
template<class Cmp>
bool matrix_sort(int** m, int N, int M, Cmp cmp);
int** matrix_input(std::istream& _in, int& N, int& M);
void matrix_output(std::ostream& _out, int** m, int N, int M);
void matrix_free(int** m, int N);
struct icmp {
int n;
icmp(int _n):n(_n){}
bool operator () (int x) const {
return ((x % n) == 0);
}
};
int main(void){
int** m, N, M;
/* ввод из файла
std::ifstream fp("matrix.txt");
m = matrix_input(fp, N, M);
fp.close();
if(m == NULL)
return 1;
matrix_output(std::cout, m, N, M);
matrix_sort(m, N, M, icmp(3));
matrix_output(std::cout, m, N, M);
matrix_free(m, N);
*/
m = matrix_input(std::cin, N, M);
if(m == NULL)
return 1;
matrix_output(std::cout, m, N, M);
//сортируем строки матрицы по-числу кратному 3-ём
matrix_sort(m, N, M, icmp(3));
matrix_output(std::cout, m, N, M);
matrix_free(m, N);
return 0;
}
//сортировка строк матрицы
template<class Cmp>
bool matrix_sort(int** m, int N, int M, Cmp cmp){
int* cs = new (std::nothrow) int[N];
if(cs == NULL)
return false;
for(int i = 0; i < N; ++i){
cs[i] = 0;
for(int j = 0; j < M; ++j){
if(cmp(m[i][j]))
++cs[i];
}
}
m_qsort(m, cs, M, 0, N - 1);
delete[] cs;
return true;
}
//ввод матрицы из входного потока
int** matrix_input(std::istream& _in, int& N, int& M){
int** m, i, j;
if(!(_in >> N >> M) || (N <= 1) || (M <= 1))
return NULL;
m = new (std::nothrow) int*[N];
if(m == NULL)
return NULL;
for(i = 0; i < N; ++i){
m[i] = new (std::nothrow) int[M];
if(m[i] == NULL){
--i;
goto err;
}
j = 0;
while((j < M) && (_in >> m[i][j]) && !_in.fail())
++j;
if(j != M)
goto err;
}
return m;
err:
for(j = i; j >= 0; --j)
delete[] m[j];
delete[] m;
return NULL;
}
//вывод матрицы в выходной поток
void matrix_output(std::ostream& _out, int** m, int N, int M){
for(int i = 0; i < N; ++i){
for(int j = 0; j < M; ++j)
_out << m[i][j] << ' ';
_out << std::endl;
}
_out << std::endl;
}
//удаление матрицы
void matrix_free(int** m, int N){
for(int i = 0; i < N; ++i)
delete[] m[i];
delete[] m;
}
//базовая быстрая сортировка
void m_qsort(int** m, int* cs, int M, int l, int r){
int p, i = l, j = r;
if(l >= r)
return;
p = cs[l + (r - l) / 2];
while(i <= j){
while(cs[i] < p)
++i;
while(cs[j] > p)
--j;
if(i <= j){
for(int v = 0; v < M; ++v)
std::swap(m[i][v], m[j][v]);
std::swap(cs[i], cs[j]);
++i;
--j;
}
}
if(j > l)
m_qsort(m, cs, M, l, j);
if(r > i)
m_qsort(m, cs, M, i, r);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnN0cmVhbT4Kdm9pZCAgbV9xc29ydChpbnQqKiBtLCBpbnQqIGNzLCBpbnQgTSwgaW50IGwsIGludCByKTsKdGVtcGxhdGU8Y2xhc3MgQ21wPgpib29sICBtYXRyaXhfc29ydChpbnQqKiBtLCBpbnQgTiwgaW50IE0sIENtcCBjbXApOwppbnQqKiBtYXRyaXhfaW5wdXQoc3RkOjppc3RyZWFtJiBfaW4sIGludCYgTiwgaW50JiBNKTsKdm9pZCAgbWF0cml4X291dHB1dChzdGQ6Om9zdHJlYW0mIF9vdXQsIGludCoqIG0sIGludCBOLCBpbnQgTSk7CnZvaWQgIG1hdHJpeF9mcmVlKGludCoqIG0sIGludCBOKTsKCnN0cnVjdCBpY21wIHsKCWludCBuOwoJaWNtcChpbnQgX24pOm4oX24pe30KCglib29sIG9wZXJhdG9yICgpIChpbnQgeCkgY29uc3QgewoJCXJldHVybiAoKHggJSBuKSA9PSAwKTsKCX0KfTsKCmludCBtYWluKHZvaWQpewoJaW50KiogbSwgTiwgTTsKLyogINCy0LLQvtC0INC40Lcg0YTQsNC50LvQsAoJc3RkOjppZnN0cmVhbSBmcCgibWF0cml4LnR4dCIpOwoJbSA9IG1hdHJpeF9pbnB1dChmcCwgTiwgTSk7CglmcC5jbG9zZSgpOwoJaWYobSA9PSBOVUxMKQoJCXJldHVybiAxOwoJbWF0cml4X291dHB1dChzdGQ6OmNvdXQsIG0sIE4sIE0pOwoJbWF0cml4X3NvcnQobSwgTiwgTSwgaWNtcCgzKSk7CgltYXRyaXhfb3V0cHV0KHN0ZDo6Y291dCwgbSwgTiwgTSk7CgltYXRyaXhfZnJlZShtLCBOKTsKKi8KCW0gPSBtYXRyaXhfaW5wdXQoc3RkOjpjaW4sIE4sIE0pOwoJaWYobSA9PSBOVUxMKQoJCXJldHVybiAxOwoJbWF0cml4X291dHB1dChzdGQ6OmNvdXQsIG0sIE4sIE0pOwoJCgkvL9GB0L7RgNGC0LjRgNGD0LXQvCDRgdGC0YDQvtC60Lgg0LzQsNGC0YDQuNGG0Ysg0L/Qvi3Rh9C40YHQu9GDINC60YDQsNGC0L3QvtC80YMgMy3RkdC8CgltYXRyaXhfc29ydChtLCBOLCBNLCBpY21wKDMpKTsKCW1hdHJpeF9vdXRwdXQoc3RkOjpjb3V0LCBtLCBOLCBNKTsKCW1hdHJpeF9mcmVlKG0sIE4pOwoJcmV0dXJuIDA7Cn0KCi8v0YHQvtGA0YLQuNGA0L7QstC60LAg0YHRgtGA0L7QuiDQvNCw0YLRgNC40YbRiwp0ZW1wbGF0ZTxjbGFzcyBDbXA+CmJvb2wgbWF0cml4X3NvcnQoaW50KiogbSwgaW50IE4sIGludCBNLCBDbXAgY21wKXsKCWludCogY3MgPSBuZXcgKHN0ZDo6bm90aHJvdykgaW50W05dOwoJaWYoY3MgPT0gTlVMTCkKCQlyZXR1cm4gZmFsc2U7CgoJZm9yKGludCBpID0gMDsgaSA8IE47ICsraSl7CgkJY3NbaV0gPSAwOwoJCWZvcihpbnQgaiA9IDA7IGogPCBNOyArK2opewoJCQlpZihjbXAobVtpXVtqXSkpCgkJCQkrK2NzW2ldOwoJCX0KCX0KCW1fcXNvcnQobSwgY3MsIE0sIDAsIE4gLSAxKTsKCWRlbGV0ZVtdIGNzOwoJcmV0dXJuIHRydWU7Cn0KCi8v0LLQstC+0LQg0LzQsNGC0YDQuNGG0Ysg0LjQtyDQstGF0L7QtNC90L7Qs9C+INC/0L7RgtC+0LrQsAppbnQqKiBtYXRyaXhfaW5wdXQoc3RkOjppc3RyZWFtJiBfaW4sIGludCYgTiwgaW50JiBNKXsKCWludCoqIG0sIGksIGo7CglpZighKF9pbiA+PiBOID4+IE0pIHx8IChOIDw9IDEpIHx8IChNIDw9IDEpKQoJCXJldHVybiBOVUxMOwoKCW0gPSBuZXcgKHN0ZDo6bm90aHJvdykgaW50KltOXTsKCWlmKG0gPT0gTlVMTCkKCQlyZXR1cm4gTlVMTDsKCglmb3IoaSA9IDA7IGkgPCBOOyArK2kpewoJCW1baV0gPSBuZXcgKHN0ZDo6bm90aHJvdykgaW50W01dOwoJCWlmKG1baV0gPT0gTlVMTCl7CgkJCS0taTsKCQkJZ290byBlcnI7CgkJfQoKCQlqID0gMDsKCQl3aGlsZSgoaiA8IE0pICYmIChfaW4gPj4gbVtpXVtqXSkgJiYgIV9pbi5mYWlsKCkpCgkJCSsrajsKCgkJaWYoaiAhPSBNKQoJCQlnb3RvIGVycjsKCX0KCXJldHVybiBtOwplcnI6Cglmb3IoaiA9IGk7IGogPj0gMDsgLS1qKQoJCWRlbGV0ZVtdIG1bal07CglkZWxldGVbXSBtOwoJcmV0dXJuIE5VTEw7Cn0KCi8v0LLRi9Cy0L7QtCDQvNCw0YLRgNC40YbRiyDQsiDQstGL0YXQvtC00L3QvtC5INC/0L7RgtC+0LoKdm9pZCBtYXRyaXhfb3V0cHV0KHN0ZDo6b3N0cmVhbSYgX291dCwgaW50KiogbSwgaW50IE4sIGludCBNKXsKCWZvcihpbnQgaSA9IDA7IGkgPCBOOyArK2kpewoJCWZvcihpbnQgaiA9IDA7IGogPCBNOyArK2opCgkJCV9vdXQgPDwgbVtpXVtqXSA8PCAnICc7CgkJX291dCA8PCBzdGQ6OmVuZGw7Cgl9Cglfb3V0IDw8IHN0ZDo6ZW5kbDsKfQoKLy/Rg9C00LDQu9C10L3QuNC1INC80LDRgtGA0LjRhtGLCnZvaWQgbWF0cml4X2ZyZWUoaW50KiogbSwgaW50IE4pewoJZm9yKGludCBpID0gMDsgaSA8IE47ICsraSkKCQlkZWxldGVbXSBtW2ldOwoJZGVsZXRlW10gbTsKfQoKLy/QsdCw0LfQvtCy0LDRjyDQsdGL0YHRgtGA0LDRjyDRgdC+0YDRgtC40YDQvtCy0LrQsAp2b2lkIG1fcXNvcnQoaW50KiogbSwgaW50KiBjcywgaW50IE0sIGludCBsLCBpbnQgcil7CglpbnQgcCwgaSA9IGwsIGogPSByOwoJaWYobCA+PSByKQoJCXJldHVybjsKCQoJcCA9IGNzW2wgKyAociAtIGwpIC8gMl07Cgl3aGlsZShpIDw9IGopewoJCXdoaWxlKGNzW2ldIDwgcCkKCQkJKytpOwoJCXdoaWxlKGNzW2pdID4gcCkKCQkJLS1qOwoKCQlpZihpIDw9IGopewoJCQlmb3IoaW50IHYgPSAwOyB2IDwgTTsgKyt2KQoJCQkJc3RkOjpzd2FwKG1baV1bdl0sIG1bal1bdl0pOwoJCQlzdGQ6OnN3YXAoY3NbaV0sIGNzW2pdKTsKCQkJKytpOwoJCQktLWo7CgkJfQoJfQoKCWlmKGogPiBsKQoJCW1fcXNvcnQobSwgY3MsIE0sIGwsIGopOwoJaWYociA+IGkpCgkJbV9xc29ydChtLCBjcywgTSwgaSwgcik7Cn0=