2.19 Error Correction
2.19.1 时空限制
Time limit: 1 Seconds Memory limit: 32768K
2.19.2 题目内容
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 × 4 matrix which has the parity property:
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 nintegers 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
2.19.3 题目来源
University of Ulm Local Contest 1998
2.19.4 汉语翻译
1.题目
错 误 纠 正
一个布尔矩阵有一种奇偶性,即该矩阵所有行和所有列的和都是一个偶数。下面这个4 × 4 的矩阵就具有奇偶性:
1 0 1 0
0 0 0 0
1 1 1 1
0 1 0 1
它所有行的和是 2,0,4 和 2。它所有列的和是 2,2,2 和 2。
你的工作就是编写一个程序,读入这个矩阵并检查它是否具有奇偶性。如果没有,你的程序应当再检查一下它是否可以通过修改一位(把 0 修改为 1,把 1 修改为 0)来使它具有奇偶性。如果不可能,这个矩阵就被认为是破坏了。
2.输入描述
输入包含多个测试案例。每个测试案例的第一行是一个整数 n(n < 100),代表该矩阵的大小。在接下来的 n 行中,每行有 n 个整数。矩阵是由 0 或 1 构成的。n 是 0 时,表示输入的结束。
3.输出描述
对于输入文件中的每个矩阵,打印一行。如果这个矩阵具有奇偶性,那么打印“OK”。如果奇偶性能通过只修改该矩阵中的一位来建立,那么打印“Change bit (i,j)”,这里 i 和 j 是被修改的这位的行号和列号。否则,打印“Corrupt”。
4.输入样例
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
5.输出样例
OK
Change bit (2,3)
Corrupt
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
int n,i,j,k,l;
int a[101][101];
while(cin>>n)
{
if(n==0) break;
for(i=0;i<n;i++)
{
a[i][n]=0;
for(j=0;j<n;j++)
{
cin>>a[i][j];
a[i][n]+=a[i][j]; //行的和
}
}
for(j=0;j<n;j++)
{
a[n][j]=0;
for(i=0;i<n;i++)
{
a[n][j]+=a[i][j]; //列的和
}
}
for(i=0;i<n;i++)
{
if(a[i][n]%2!=0)
{
goto NL;
}
}
for(j=0;j<n;j++)
{
if(a[n][j]%2!=0)
{
goto NR;
}
}
if(i==n&&j==n)
{
cout<<"OK"<<endl;
continue;
}
NL:
if(a[i][0]==0)
a[i][0]=1;
else
a[i][0]=0;
goto JY;
NR:
if(a[0][j]==0)
a[0][j]=1;
else
a[0][j]=0;
goto JY;
JY:
for(k=0;k<n;k++)
{
if(a[k][n]%2!=0)
break;
}
for(l=0;l<n;l++)
{
if(a[n][l]%2!=0)
break;
}
if(k!=n&&l!=n)
{
cout<<"Change bit("<<k+1<<","<<l+1<<")"<<endl;
continue;
}
else
goto LN;
LN:
cout<<"Corrupt"<<endl;
continue;
}
return 0;
}
2.19.5 解题思路
本题是判断一个矩阵是否具有奇偶性。这点好办,计算一下每行每列的和是否是偶数就好了,但还需要判断一个没有奇偶性的矩阵是否可以通过修改唯一一位来使之具有奇偶性,这是难点。
当只有一行的和是奇数且只有一列的和为奇数,那么,将这两行交点处的元素修改一下,就变成具有 parity property(奇偶性)的矩阵了。这里还要清楚的一点是,在一个矩阵中,任何一行与任何一列都有且仅有一个交点。
需要指出的是,如果定义一个过大的数组或容器,应当把它们定义为全局变量为宜,这样,可以获得尽可能大的内存分配。这种情况,不宜定义在函数范围内的变量(局部变量)。
2.19.6 参考答案
#include <iostream>
using namespace std;
int matrix[100][100]; //全局数组
int SL[100];//数组每行的和
int SC[100];//数组每列的和
int main(int argc, char* argv[])
{
ifstream cin("aaa.txt");
//先定义好各种循环变量
int i,j,PL,PC,CountL,CountC;
int n;//矩阵行数或列数
while(cin>>n)
{
if(n==0)break;//读入数据结束
//初始化各种变量和数组
PL=0;
PC=0;
CountL=0;
CountC=0;
for(i=0;i<n;i++)
{
SL[i]=0;
SC[i]=0;
}
//读入所有数据,同时计算出每行、列的元素和
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cin>>matrix[i][j];
SL[i]=SL[i]+matrix[i][j];
SC[j]=SC[j]+matrix[i][j];
}
}
//判断矩阵每行、列的和是否是偶数
for(i=0;i<n;i++)
{
//判断每行的和
if(SL[i]%2!=0)//和是奇数
{
PL=i;//记下行数
CountL++;//记下次数
}
//判断每列的和
if(SC[i]%2!=0)//和是奇数
{
PC=i;//记下列数
CountC++;//记下次数
}
}
//输出结果
if(CountL==0 && CountC==0)
cout<<"OK"<<endl;
else if(CountL==1 && CountC==1)
cout<<"Change bit ("<<PL+1<<","<<PC+1<<")"<<endl;
else
cout<<"Corrupt"<<endl;
}
return 0;
}