题目
分析
要求消除n*m矩阵中一行或者一列相同的,可以转换为一个更小的问题:如何消除一个数组中超过三个相同的数字。
void solve(int *a,int size)//消除数组a[ size ]中超过3次相同的数字:l 用来记录当前段的开头,r用来记录当前遍历的数字。进入下一段(数字开始不同)的时候,先判断一下当前段是否可以消除,可以就置为0。
while(r<size-1){
r++;
if(a[r]!=a[l]){//下一个段
//进入下一段之前判断是否能消除
if(r-l>=3){
for(int i=l;i<r;i++){
a[i]=0;//置为0
}
}
l=r;
}
}
要注意的是,这个是遇到不同的数字就处理上一段,所以最后一段没有处理,需要单独拿出来处理。
if(r==size-1){//最后面的情况
if(r-l>=2){
for(int i=l;i<=r;i++){
a[i]=0;//置为0
}
}
}
最后遍历这个矩阵的每一行和每一列,进行上面的操作,就可以解决问题了。
代码
#include<stdio.h>
using namespace std;
int n,m,G1[35][35],G2[35][35];
void solve(int* a,int size){
int l=0,r=0;
while(r<size-1){
r++;
if(a[r]!=a[l]){//下一个段
//进入下一段之前判断是否能消除
if(r-l>=3){
for(int i=l;i<r;i++){
a[i]=0;//置为0
}
}
l=r;
}
if(r==size-1){//最后面的情况
if(r-l>=2){
for(int i=l;i<=r;i++){
a[i]=0;//置为0
}
}
}
}
}
int main()
{
int v;
scanf("%d %d",&n,&m);//n行m列
for(int i=0;i<n;i++){//读入数据
for(int j=0;j<m;j++){
scanf("%d",&v);
G1[i][j]=v;G2[j][i]=v;
}
}
for(int i=0;i<n;i++)//一行一行来
solve(G1[i],m);
for(int i=0;i<m;i++)
solve(G2[i],n);
//然后合并
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(G1[i][j]==0||G2[j][i]==0)
printf("0");
else printf("%d",G1[i][j]);
if(j!=m-1) printf(" ");
}
printf("\n");
}
return 0;
}