【回溯】B036_LQ_整理玩具(区域染色)

   日期:2020-08-22     浏览:101    评论:0    
核心提示:小明有一套玩具,一共包含NxM个部件。这些部件摆放在一个包含NxM个小格子的玩具盒中,每个小格子中恰好摆放一个部件。每一个部件上标记有一个0~9的整数,有可能有多个部件标记相同的整数。小明对玩具的摆放有特殊的要求:标记相同整数的部件必须摆在一起,组成一个矩形形状。如以下摆放是满足要求的:000220003344444 1224412244122330123456789以下摆放不满足要求:111221112233311111111122221122221111111

小明有一套玩具,一共包含NxM个部件。这些部件摆放在一个包含NxM个小格子的玩具盒中,每个小格子中恰好摆放一个部件。

每一个部件上标记有一个0~9的整数,有可能有多个部件标记相同的整数。

小明对玩具的摆放有特殊的要求:标记相同整数的部件必须摆在一起,组成一个矩形形状。如以下摆放是满足要求的:

00022
00033
44444  

12244
12244
12233

01234
56789
以下摆放不满足要求:
11122
11122
33311

111111
122221
122221
111111

11122
11113
33333

给出一种摆放方式,请你判断是否符合小明的要求。

输入
输入包含多组数据。
第一行包含一个整数T,代表数据组数。 (1 <= T <= 10)
以下包含T组数据。
每组数据第一行包含两个整数N和M。 (1 <= N, M <= 10)
以下包含N行M列的矩阵,代表摆放方式。

输出
对于每组数据,输出YES或者NO代表是否符合小明的要求。

样例输入
3  
3 5  
00022
00033
44444  
3 5  
11122
11122
33311
2 5  
01234
56789
样例输出
YES
NO
YES
方法一:区域染色

核心是检查矩形这:由于是矩形,需要记录搜到的最远位置(即矩形右下角 ex, ey),检查是否是矩形就是枚举面积为 (ex-i) × (ey-j) 的矩形是否在一次遍历后染成同一种颜色的格子的数量等于该颜色全局的数量且数量等于 (ex-i) × (ey-j)

#include<bits/stdc++.h>
using namespace std;

const int N=15, d[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };
int ex, ey, n, m, cnt[N], now[N], mark[N][N];
char g[N][N];
void dfs(int i, int j, int c) {
    ex=max(ex, i), ey=max(ey, j);
    mark[i][j]=c, now[g[i][j]-'0']++;
    for (int k=0; k<4; k++) {
        int ni=i+d[k][0], nj=j+d[k][1];
        if (ni>=0 && ni<n && nj>=0 && nj<m && mark[ni][nj]==0 && g[i][j]==g[ni][nj]) {
            dfs(ni, nj, c);
        }
    }
}
bool chk() {
    int color=1; 
    for (int i=0; i<n; i++)
    for (int j=0; j<m; j++) if (mark[i][j]==0) {
        ex=-1, ey=-1;
        dfs(i, j, color++);
        if (now[g[i][j]-'0'] != cnt[g[i][j]-'0']) return false;
        for (int ii=i; ii<=ex; ii++)
        for (int jj=j; jj<=ey; jj++) if (mark[ii][jj]!=mark[i][j]) 
            return false;
    }
    return true;
}
int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    int T; cin>>T;
    while (T--) {
        cin>>n>>m;
        memset(cnt, 0, sizeof cnt), memset(now, 0, sizeof now), memset(mark, 0, sizeof mark);
        for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) {
            cin>>g[i][j];
            cnt[g[i][j]-'0']++;
        }
        cout << (chk() ? "YES" : "NO") << '\n';
    }
    return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服