// File: cooljacket[P]Dormitory-distribution/main.cpp
// Function: divide(std::vector<Student, std::allocator<Student>>&, std::vector<Student, std::allocator<Student>>&, std::ostream&)
void divide(vector<Student>& GroupA, vector<Student>& GroupB, ostream& out) {
	if (GroupA.size() > GroupB.size())
		swap(GroupA, GroupB);

	// Step 1: 使用kmeans抽取GroupB中尽量不同的人到GroupA中
	int num = (GroupB.size() - GroupA.size()) / 2;
	if (num > 0) {
		KMeans<Student> km(GroupB, num, 15);
		km.train_inc();
		km.explain();
		vector<size_t> reps = km.getSortedRepresentative();
		for (int i = reps.size()-1, j=GroupB.size()-1; i >= 0; --i, --j) {
			swap(GroupB[reps[i]], GroupB[j]);
		}
		for (int i = 0; i < num; ++i) {
			GroupA.push_back(*(GroupB.rbegin()));
			GroupB.pop_back();
		}
	}



	// Step 2: 每个组内按相似度两两结合，没法结合的元素单独放到“special宿舍”中
	vector<Student> special;
	vector<Student> CombA, CombB;
	vector<pair<Student, Student> > CombAPairs, CombBPairs;
	CombGroupIntoPairs(GroupA, CombA, CombAPairs, special);
	CombGroupIntoPairs(GroupB, CombB, CombBPairs, special);


	// Step 3: 对于每个两两组合后的“平均者”，CombA在CombB中寻找最相似的，作为同个宿舍的划分
	// 从CombA的最后面开始配对，将CombB中与其最相似的那个交换到尾部，方便降低删除的复杂度
	vector<vector<Student> > result;
	for (int i = CombA.size()-1; i >= 0; --i) {
		vector<Student> unit;
		size_t goal = findNearestExclude(CombA[i], CombB, CombB.size());
		unit.push_back(CombAPairs[i].first);
		unit.push_back(CombAPairs[i].second);
		unit.push_back(CombBPairs[goal].first);
		unit.push_back(CombBPairs[goal].second);
		result.push_back(unit);
		
		if (goal != CombB.size()-1) {
			swap(CombB[goal], *(CombB.rbegin()));
			swap(CombBPairs[goal], *(CombBPairs.rbegin()));
		}
		CombB.pop_back();
		CombBPairs.pop_back();
	}

	// CombB最后的size只可能是0或1
	if (CombB.size() == 1) {
		special.push_back(CombBPairs[0].first);
		special.push_back(CombBPairs[0].second);
	}

	if (!special.empty())
		result.push_back(special);

	out << "宿舍号,学号,姓名,性别,生源地,起床时间,就寝时间,兴趣爱好,性格,易受他人影响,集体住宿经历,家庭人均收入,喜欢开空调" << endl;
	for (int i = 0; i < result.size(); ++i) {
		out << i+1;
		for (int j = 0; j < result[i].size(); ++j) {
			out << ',';
			result[i][j].output(out);
		}
		out << endl;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2e0, %rsp            # imm = 0x2E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0x67b0
movq %rax, -0x210(%rbp)
movq -0x10(%rbp), %rdi
callq 0x67b0
movq %rax, %rcx
movq -0x210(%rbp), %rax
cmpq %rcx, %rax
jbe 0x59cc
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6b40
movq -0x10(%rbp), %rdi
callq 0x67b0
movq %rax, -0x218(%rbp)
movq -0x8(%rbp), %rdi
callq 0x67b0
movq %rax, %rcx
movq -0x218(%rbp), %rax
subq %rcx, %rax
shrq %rax
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jle 0x5bdd
movq -0x10(%rbp), %rsi
movslq -0x1c(%rbp), %rdx
leaq -0xf8(%rbp), %rdi
movq %rdi, -0x220(%rbp)
movl $0xf, %ecx
callq 0x6b70
movq -0x220(%rbp), %rdi
callq 0x6d70
jmp 0x5a30
leaq -0xf8(%rbp), %rdi
callq 0x6fd0
jmp 0x5a3e
leaq -0x120(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x70a0
jmp 0x5a53
leaq -0x120(%rbp), %rdi
callq 0x71c0
subq $0x1, %rax
movl %eax, -0x124(%rbp)
movq -0x10(%rbp), %rdi
callq 0x67b0
subq $0x1, %rax
movl %eax, -0x128(%rbp)
cmpl $0x0, -0x124(%rbp)
jl 0x5b13
movq -0x10(%rbp), %rax
movq %rax, -0x230(%rbp)
movslq -0x124(%rbp), %rsi
leaq -0x120(%rbp), %rdi
callq 0x71e0
movq -0x230(%rbp), %rdi
movq (%rax), %rsi
callq 0x6930
movq %rax, -0x228(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x128(%rbp), %rsi
callq 0x6930
movq -0x228(%rbp), %rdi
movq %rax, %rsi
callq 0x6950
movl -0x124(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x124(%rbp)
movl -0x128(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x128(%rbp)
jmp 0x5a7c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x5bcc
movl $0x0, -0x12c(%rbp)
movl -0x12c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x5bb2
movq -0x8(%rbp), %rax
movq %rax, -0x248(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x138(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0x7200
movq -0x240(%rbp), %rdi
callq 0x7250
movq %rax, -0x238(%rbp)
jmp 0x5b63
movq -0x238(%rbp), %rsi
movq -0x248(%rbp), %rdi
callq 0x6650
jmp 0x5b78
movq -0x10(%rbp), %rdi
callq 0x6b10
movl -0x12c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x12c(%rbp)
jmp 0x5b1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x7280
jmp 0x5bcc
leaq -0x120(%rbp), %rdi
callq 0x7280
leaq -0xf8(%rbp), %rdi
callq 0x72e0
jmp 0x5bdd
leaq -0xf8(%rbp), %rdi
callq 0x72e0
jmp 0x618d
leaq -0x150(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0x7350
leaq -0x168(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x7350
leaq -0x180(%rbp), %rdi
callq 0x7350
leaq -0x198(%rbp), %rdi
movq %rdi, -0x258(%rbp)
callq 0x7370
leaq -0x1b0(%rbp), %rdi
callq 0x7370
movq -0x260(%rbp), %rsi
movq -0x258(%rbp), %rdx
movq -0x250(%rbp), %rcx
movq -0x8(%rbp), %rdi
callq 0x6280
jmp 0x5c4e
movq -0x10(%rbp), %rdi
leaq -0x180(%rbp), %rsi
leaq -0x1b0(%rbp), %rdx
leaq -0x150(%rbp), %rcx
callq 0x6280
jmp 0x5c6e
leaq -0x1c8(%rbp), %rdi
callq 0x7390
leaq -0x168(%rbp), %rdi
callq 0x67b0
subq $0x1, %rax
movl %eax, -0x1cc(%rbp)
cmpl $0x0, -0x1cc(%rbp)
jl 0x5f21
leaq -0x1e8(%rbp), %rdi
callq 0x7350
movslq -0x1cc(%rbp), %rsi
leaq -0x168(%rbp), %rdi
callq 0x6930
movq %rax, -0x278(%rbp)
leaq -0x180(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x67b0
movq -0x278(%rbp), %rdi
movq -0x270(%rbp), %rsi
movq %rax, %rdx
callq 0x61a0
movq %rax, -0x268(%rbp)
jmp 0x5cf5
movq -0x268(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movslq -0x1cc(%rbp), %rsi
leaq -0x198(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x6650
jmp 0x5d27
movslq -0x1cc(%rbp), %rsi
leaq -0x198(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
addq $0x88, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x6650
jmp 0x5d52
movq -0x1f0(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x6650
jmp 0x5d76
movq -0x1f0(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
addq $0x88, %rsi
leaq -0x1e8(%rbp), %rdi
callq 0x6650
jmp 0x5da1
leaq -0x1c8(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x73d0
jmp 0x5db6
movq -0x1f0(%rbp), %rax
movq %rax, -0x280(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x67b0
movq %rax, %rcx
movq -0x280(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
je 0x5ee9
movq -0x1f0(%rbp), %rsi
leaq -0x180(%rbp), %rdi
movq %rdi, -0x2a0(%rbp)
callq 0x6930
movq -0x2a0(%rbp), %rsi
movq %rax, -0x298(%rbp)
leaq -0x1f8(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x7200
movq -0x290(%rbp), %rdi
callq 0x7250
movq %rax, -0x288(%rbp)
jmp 0x5e37
movq -0x288(%rbp), %rsi
movq -0x298(%rbp), %rdi
callq 0x6950
movq -0x1f0(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x73b0
movq -0x2c0(%rbp), %rsi
movq %rax, -0x2b8(%rbp)
leaq -0x200(%rbp), %rdi
movq %rdi, -0x2b0(%rbp)
callq 0x7470
movq -0x2b0(%rbp), %rdi
callq 0x74c0
movq %rax, -0x2a8(%rbp)
jmp 0x5e9a
movq -0x2a8(%rbp), %rsi
movq -0x2b8(%rbp), %rdi
callq 0x7440
jmp 0x5ee9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x6151
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x7520
jmp 0x6145
leaq -0x180(%rbp), %rdi
callq 0x6b10
leaq -0x1b0(%rbp), %rdi
callq 0x74f0
leaq -0x1e8(%rbp), %rdi
callq 0x7520
movl -0x1cc(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1cc(%rbp)
jmp 0x5c90
leaq -0x180(%rbp), %rdi
callq 0x67b0
cmpq $0x1, %rax
jne 0x5f95
xorl %eax, %eax
movl %eax, %esi
leaq -0x1b0(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
leaq -0x150(%rbp), %rdi
callq 0x6650
jmp 0x5f54
xorl %eax, %eax
movl %eax, %esi
leaq -0x1b0(%rbp), %rdi
callq 0x73b0
movq %rax, %rsi
addq $0x88, %rsi
leaq -0x150(%rbp), %rdi
callq 0x6650
jmp 0x5f7c
jmp 0x5f95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x100(%rbp)
movl %eax, -0x104(%rbp)
jmp 0x6145
leaq -0x150(%rbp), %rdi
callq 0x7580
testb $0x1, %al
jne 0x5fbc
leaq -0x1c8(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x73d0
jmp 0x5fba
jmp 0x5fbc
movq -0x18(%rbp), %rdi
leaq 0x1610d(%rip), %rsi     # 0x1c0d4
callq 0x3270
movq %rax, -0x2c8(%rbp)
jmp 0x5fd5
movq -0x2c8(%rbp), %rdi
movq 0x23fd5(%rip), %rsi     # 0x29fb8
callq 0x32b0
jmp 0x5fea
movl $0x0, -0x204(%rbp)
movslq -0x204(%rbp), %rax
movq %rax, -0x2d0(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x75c0
movq %rax, %rcx
movq -0x2d0(%rbp), %rax
cmpq %rcx, %rax
jae 0x60f4
movq -0x18(%rbp), %rdi
movl -0x204(%rbp), %esi
incl %esi
callq 0x3430
jmp 0x6034
movl $0x0, -0x208(%rbp)
movslq -0x208(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movslq -0x204(%rbp), %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x6630
movq %rax, %rdi
callq 0x67b0
movq %rax, %rcx
movq -0x2d8(%rbp), %rax
cmpq %rcx, %rax
jae 0x60cc
movq -0x18(%rbp), %rdi
movl $0x2c, %esi
callq 0x3320
jmp 0x6086
movslq -0x204(%rbp), %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x6630
movq %rax, %rdi
movslq -0x208(%rbp), %rsi
callq 0x6930
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x132c0
jmp 0x60b6
jmp 0x60b8
movl -0x208(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x208(%rbp)
jmp 0x603e
movq -0x18(%rbp), %rdi
movq 0x23ee1(%rip), %rsi     # 0x29fb8
callq 0x32b0
jmp 0x60de
jmp 0x60e0
movl -0x204(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x204(%rbp)
jmp 0x5ff4
leaq -0x1c8(%rbp), %rdi
callq 0x6710
leaq -0x1b0(%rbp), %rdi
callq 0x75f0
leaq -0x198(%rbp), %rdi
callq 0x75f0
leaq -0x180(%rbp), %rdi
callq 0x7520
leaq -0x168(%rbp), %rdi
callq 0x7520
leaq -0x150(%rbp), %rdi
callq 0x7520
addq $0x2e0, %rsp            # imm = 0x2E0
popq %rbp
retq
leaq -0x1c8(%rbp), %rdi
callq 0x6710
leaq -0x1b0(%rbp), %rdi
callq 0x75f0
leaq -0x198(%rbp), %rdi
callq 0x75f0
leaq -0x180(%rbp), %rdi
callq 0x7520
leaq -0x168(%rbp), %rdi
callq 0x7520
leaq -0x150(%rbp), %rdi
callq 0x7520
movq -0x100(%rbp), %rdi
callq 0x3440
nopl (%rax)