Error Correction
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6820 | Accepted: 4286 |
Description
A boolean matrix has the parity property when each row and each column has an even sum, i.e. contains an even number of bits which are set. Here's a 4 x 4 matrix which has the parity property:
The sums of the rows are 2, 0, 4 and 2. The sums of the columns are 2, 2, 2 and 2.
Your job is to write a program that reads in a matrix and checks if it has the parity property. If not, your program should check if the parity property can be established by changing only one bit. If this is not possible either, the matrix should be classified as corrupt.
1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 1
The sums of the rows are 2, 0, 4 and 2. The sums of the columns are 2, 2, 2 and 2.
Your job is to write a program that reads in a matrix and checks if it has the parity property. If not, your program should check if the parity property can be established by changing only one bit. If this is not possible either, the matrix should be classified as corrupt.
Input
The input will contain one or more test cases. The first line of each test case contains one integer n (n<100), representing the size of the matrix. On the next n lines, there will be n integers per line. No other integers than 0 and 1 will occur in the matrix. Input will be terminated by a value of 0 for n.
Output
For each matrix in the input file, print one line. If the matrix already has the parity property, print "OK". If the parity property can be established by changing one bit, print "Change bit (i,j)" where i is the row and j the column of the bit to be changed. Otherwise, print "Corrupt".
Sample Input
4 1 0 1 0 0 0 0 0 1 1 1 1 0 1 0 1 4 1 0 1 0 0 0 1 0 1 1 1 1 0 1 0 1 4 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0
Sample Output
OK Change bit (2,3) Corrupt
Source
【题目大意】
给定一个n*n的由0/1构成的boolean矩阵,判断是否各行各列和均为偶数,若是输出OK,若不是,可否更改其中一点的位置使行列均为偶数。输出这个点,若不可以,输出Corrupt
【解题思路】
改一个点即可的充要条件为行和列之中存在且仅有一行与一列的各自的和为奇数。
或者利用邻接矩阵的知识转化为有向图+深度优先搜索??学姐讲的图论知识,还没有深入学习。
【解题代码】
#include <cstdio>
#include <cstring>
#define maxn 102
int map[maxn][maxn];
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
memset(map,0,sizeof(map));
int sumh=0,sumv=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
map[n+1][j]+=map[i][j];
map[i][n+1]+=map[i][j];
}
}
//solve it
int marka=0,markb=0,ans=0,bns=0;
for(int i=1;i<=n;i++)
{
if(map[n+1][i]%2)
{
bns++;
markb=i;
}
if(map[i][n+1]%2)
{
ans++;
marka=i;
}
}
if(!ans&&!bns) printf("OK\n");
else if(ans==1&&bns==1) printf("Change bit (%d,%d)\n",marka,markb);
else printf("Corrupt\n");
map[marka][markb]=!map[marka][markb];
}
}
【收获与反思】
图论知识补充:
1.我们的定义的数据对象的范围是有向图和无向图
2.图的通路:
图中的顶点与边的交替序列我们称之为是图的通路
3.欧拉通路:
我们从有向图或者无向图中的任意一点出发,将所有的边遍历且仅遍历一次的通路序列我们称之为是欧拉通路
4.欧拉回路:
如果我们的欧拉通路的起点和终点是一样的我们称之为欧拉回路
5.欧拉图:
具有欧拉回路的图称之为欧拉图,规定平凡图(只有一个顶点的空图)属于欧拉图
6.半欧拉图:
具有欧拉通路的图我们称之为是半欧拉图
一些相关定理:
1.无向连通图 G 是欧拉图,当且仅当 G 不含奇数度结点( G 的所有结点度数为偶数);
3.有向连通图 D 是欧拉图,当且仅当该图为连通图且 D 中每个结点的入度=出度;
4.有向连通图 D 含有欧拉通路,当且仅当该图为连通图且 D 中除两个结点外,其余每个结点的入度=出度,且此两点满足 deg-(u)-deg+(v)=±1 。(起始点s的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度);
5.一个非平凡连通图是欧拉图当且仅当它的每条边属于奇数个环;
6.如果图G是欧拉图且 H = G-uv,则 H 有奇数个 u,v-迹仅在最后访问 v ;同时,在这一序列的 u,v-迹中,不是路径的迹的条数是偶数。