解题思路:
1.用两个矩阵来存储 原始值,其中一个永远不改变,只用来判断 ,这样可以防止消除某一行或某一列后影响其它行或列。
2.记录下每一行每个数字出现的次数和每一列每一个数字出现的次数。
3.只有当某一行或某一列的某个数出现次数大于等于3,才需要判断是否需要消除,否则直接跳过。
4.每一行和每一列需要消除的地方可能不止一处,需要进行多次判断。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int arr[31][31]={0}; //只用来判断,永远不改变
int arr2[31][31]; //用来输出,防止消除一次后,某一个数变成0,影响其它行列
int visith[31][10]={0}; //标记数组,记录每一行每个取值有几个
int visitl[31][10]={0}; //标记数组,记录每一列每个取值有几个
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>arr[i][j];
arr2[i][j]=arr[i][j];
visith[i][arr[i][j]]++;
visitl[j][arr[i][j]]++;
}
}
for(int i=0;i<n;i++)
{
for(int j=1;j<10;j++)
{
if(visith[i][j]>=3) //只有大于等于3,才需要判断
{
int t=0; //计算有几个等于j的数
int pos=0; //开始消除的位置
for(int k=0;k<m;k++)
{
if(arr[i][k]==j)
{
t++;
}
if(t>=3&&(arr[i][k]!=j||k==m-1)) //需要消除的条件
{
for(int tm=pos;tm<k;tm++) //修改第二个矩阵,第一个矩阵永远不变
{
arr2[i][tm]=0;
}
if(arr[i][k]==j) //最后一个位置要额外判断
arr2[i][k]=0;
pos=k+1; //需要消除的位置更新
t=0; //值等于j的个数重新为0
continue; //开始下一次循环
}
if(arr[i][k]!=j) //其它情况
{
t=0;
pos=k+1;
}
}
}
}
}
for(int i=0;i<m;i++) //判断每一列时也一样
{
for(int j=1;j<10;j++)
{
if(visitl[i][j]>=3)
{
int t=0;
int pos=0;
for(int k=0;k<n;k++)
{
if(arr[k][i]==j)
{
t++;
}
if(t>=3&&(arr[k][i]!=j||k==n-1))
{
for(int tm=pos;tm<k;tm++)
{
arr2[tm][i]=0;
}
pos=k+1;
t=0;
if(arr[k][i]==j)
arr2[k][i]=0;
continue;
}
if(arr[k][i]!=j)
{
t=0;
pos=k+1;
}
}
}
}
}
for(int i=0;i<n;i++) //输出第二个矩阵
{
for(int j=0;j<m;j++)
{
cout<<arr2[i][j]<<' ';
}
cout<<endl;
}
return 0;
}