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("\n"); } fclose(stdin); fclose(stdout); return 0; }