分两步吧
第一步需要判断是否每一个数值均只有一个连通块,dfs搜索记录即可
第二步需要判断每一个连通块是否都是矩形,用两个map分别存储每一块所有点的横纵坐标,再用set加以判断
#include<bits/stdc++.h>
using namespace std;
int n,m,cnt,flag,t,flag1;
char mapp[15][15];
int vis[15][15];
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
map<int,int> m1,m2;
void dfs(int x,int y)
{
for(int i=0;i<4;i++)
{
int tx=x+dx[i];
int ty=y+dy[i];
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&vis[tx][ty]==0&&mapp[tx][ty]==mapp[x][y])
{
m1[tx]++;
m2[ty]++;
vis[tx][ty]=1;
dfs(tx,ty);
}
}
}
int main()
{
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>mapp[i][j];
}
}
flag=0;
flag1=0;
for(int i=0;i<=9;i++) //对数字从0-9
{
m1.clear();
m2.clear();
cnt=0;
for(int j=1;j<=n;j++)
{
for(int k=1;k<=m;k++)
{
if(mapp[j][k]==(i+'0')&&vis[j][k]==0)
{
vis[j][k]=1;
m1[j]++; //记录横坐标的数值
m2[k]++; //记录纵坐标的数值
dfs(j,k);
cnt++;
}
}
}
if(cnt>1)
flag=1;
set<int> s;
for(map<int,int>::iterator it=m1.begin();it!=m1.end();it++)
s.insert((*it).second);
if(s.size()>1)
flag1=1;
set<int> s1;
for(map<int,int>::iterator it=m2.begin();it!=m2.end();it++)
s1.insert((*it).second);
if(s1.size()>1)
flag1=1;
}
if(flag==1 || flag1==1) //如果不满足 每一个数值的连通块都为1且都为矩形
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}