#include <stdio.h>
#include <stdlib.h>

#define USERNUM	3			// number of rows
#define COLNUM	6			// number of columns
#define ECOLNUM	(COLNUM/2)	// number of effective columns

struct sum_with_index {
	int sum;
	int index;
} users[USERNUM], rows[USERNUM][ECOLNUM];

int answer[USERNUM];

int a[USERNUM][COLNUM] = 
	{{10,20,32,40,45,35},
	 {20,10,25,42,47,40},
	 {30,35,15,10,20,25}};

int cmp_sumorder_ascending(const void *v1, const void *v2);
int cmp_sumorder_descending(const void *v1, const void *v2);
void init();
void cal_user_order();
void cal_row_order();
void cal_answer();
void out_answer();

int main() {
	int i, j;

	// initialize some data structure, users and rows literally
	init();

	// calculate the order of users
	cal_user_order();
	/* DEBUG
	 * for(i = 0; i < USERNUM; i++)
		printf("%d\t%d\n", users[i].sum, users[i].index);*/

	// calculate the order of each row
	cal_row_order();
	/* DEBUG
	 * for(i = 0; i < USERNUM; i++) {
		for(j = 0; j < ECOLNUM; j++)
			printf("%d,%d\t", rows[i][j].sum, rows[i][j].index);
		printf("\n");
	}*/

	// according to the order of users, iterate each row and calculate the answer
	cal_answer();

	// print out the answers
	out_answer(a, answer);

	return 0;
}

int cmp_sumorder_ascending(const void *v1, const void *v2) {
	if(((struct sum_with_index const *)v1)->sum > ((struct sum_with_index const *)v2)->sum) return 1;
	else if(((struct sum_with_index const *)v1)->sum == ((struct sum_with_index const *)v2)->sum) return 0;
	else return -1;
}

int cmp_sumorder_descending(const void *v1, const void *v2) {
	if(((struct sum_with_index const *)v1)->sum > ((struct sum_with_index const *)v2)->sum) return -1;
	else if(((struct sum_with_index const *)v1)->sum == ((struct sum_with_index const *)v2)->sum) return 0;
	else return 1;
}

void init() {
	int i, j;
	// calculate the sum of each user, and the sum of each pair in each row
	for(i = 0; i < USERNUM; i++) {
		users[i].sum = 0;
		users[i].index = i;
		for(j = 0; j < COLNUM; j++) {
			users[i].sum += a[i][j];
			if(j%2) {
				rows[i][(j-1)/2].sum = a[i][j-1] + a[i][j];
				rows[i][(j-1)/2].index = (j-1)/2;
			}
		}
	}
}

void cal_user_order() {
	qsort(users, USERNUM, sizeof(struct sum_with_index), cmp_sumorder_ascending);
}

void cal_row_order() {
	int i;
	for(i = 0; i < USERNUM; i++)
		qsort(rows[i], ECOLNUM, sizeof(struct sum_with_index), cmp_sumorder_descending);
}

void cal_answer() {
	int chosen[ECOLNUM] = {0};
	int i, j;

	for(i = 0; i < USERNUM; i++)
		for(j = 0; j < ECOLNUM; j++)
			if(0 == chosen[rows[users[i].index][j].index]) {
				chosen[rows[users[i].index][j].index] = 1;
				answer[users[i].index] = rows[users[i].index][j].index;
				break;
			}
}

void out_answer() {
	int i, j;
	for(i = 0; i < USERNUM; i++)
		printf("User%d: %d %d\n", i+1, a[i][answer[i]*2], a[i][answer[i]*2+1]);
}
