gcj_2016_Round1_B

题目

    一个NxN的矩阵,矩阵中每个方格中都有一个数值,且每一行的数值严格单调递增,每一列的数值严格单调递增。分别取出N行和N列,形成2N个长度为N的数组,现在有一个数组丢失,已知剩下的2N-1个长度为N的数组,求出丢失的那个数组。

实现

    开始做的时候,试图一行一行,一列一列的进行递推枚举,重建出原来的NxN的矩阵。做的时候,越写越麻烦。。。。看了别人的题解才发现自己的解法是多么傻。
    由于NxN的方格中每个数字都出现两次,一次是在该数字所在的行的数组中出现,一次是在该数字所在的列的数组中出现。那么,如果不发生丢失,则 N*2N个数字中每个数字都出现了偶数次(因为矩阵中可能存在相同的数字);丢失的那个长度为N的数组中的数字在 N*(2N-1)个已经给出的数字中只出现了奇数次。
    于是,只要找到在N*(2N-1)个已经给出的数字中只出现了奇数次的数字即可。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<deque>
#include<string>
#include<unordered_map>
#include<unordered_set>
using namespace std;
int num_count[2505];
int main() {
	freopen("./apactest/B-large-practice.in", "r", stdin);
	freopen("./apactest/B-large-practice.out", "w", stdout);
	int T, N, num;
	scanf("%d", &T);
	for (int cas = 1; cas <= T; cas++) {
		scanf("%d", &N);
		memset(num_count, 0, sizeof(num_count));
		for (int i = 0; i < 2 * N - 1; i++) {
			for (int j = 0; j < N; j++) {
				scanf("%d", &num);
				num_count[num] ^= 1; //异或运算进行奇偶交替
			}
		}
		printf("Case #%d:", cas);
		for (int i = 1; i <= 2500; i++) { //个数为奇数的数字,就是丢掉的那张纸条上的数字
			if (num_count[i])
				printf(" %d", i);
		}
		printf("
");
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
}
原文地址:https://www.cnblogs.com/gtarcoder/p/5542596.html