zoukankan      html  css  js  c++  java
  • 判别数字图片能否「一笔完成」

    每张给定的数字图片只有2种像素值,即0和255,如下所示:
    实例1
    现给定全黑的一张背景图,用一支笔可以连续地在上下左右斜对角共8个方向移动,可以允许重复地经过一处。笔经过处像素值会变为0,即变成白色。如果这样操作后能得到一张如上所示的数字图片,则称该数字图片可以「一笔完成」。

    下面是不能「一笔完成」的数字图片例子:
    实例2
    因为要完成“6”中间部分的「白圈」,必须要把「笔」拿起来放到对应的位置移动。

    将数字“6”用pandas可视化如下所示,这里去掉像素值全为0的部分列:

    也就说,需要给定一个程序判断是否有一堆「0」被一堆「255」围住,如果是的话,这张数字图片就是不能「一笔完成」的。我这里用的办法是深度搜索,往上下左右4个方向深搜,判断图片中有几堆「0」。如果仅有1堆,那么这个数字图片可以「一笔完成」;反之。

    代码

    mnist.npz的百度云盘,密码bwn1

    import numpy as np
    
    # 读取函数,数据都被保存在mnist.npz
    def load_data():
        data = np.load('./mnist.npz')
        X = data['X']
        return X
    
    def DFS(X, row, col, visited):
        visited[row][col] = 1
        if X[row][col] == 255:
            return
        if row+1 < 28 and visited[row+1][col] == 0:
            DFS(X, row+1, col, visited)
        if col+1 < 28 and visited[row][col+1] == 0:
            DFS(X, row, col+1, visited)
        if row-1 >= 0 and visited[row-1][col] == 0:
            DFS(X, row-1, col, visited)
        if col-1 >= 0 and visited[row][col-1] == 0:
            DFS(X, row, col-1, visited)
    
    if __name__ == '__main__':
        X = load_data()
        # X.shape = (10000, 28, 28)
        success = 0  # 可以「一笔完成」的数字图片总数
        for t in range(10000):
            blocks = 0  # 数字图片中存在几堆「0」
            visited = np.zeros((28, 28))  # 标记数组
            for i in range(28):
                for j in range(28):
                    if X[t][i][j] == 0 and visited[i][j] == 0:
                        DFS(X[t], i, j, visited)
                        blocks += 1
            if blocks == 1:
                success += 1
    
        print(success)
    
  • 相关阅读:
    【题解】[USACO08DEC-Gold] Trick or Treat on the Farm
    【题解】[NOIP2015-TG] 信息传递
    【题解】[JLOI2011] 飞行路线
    平衡树
    斜率优化 dp 总结
    题解【P1833 樱花】
    题解【CodeForces 910A The Way to Home】
    三角恒等变换公式
    题解【洛谷 P1246 编码】
    生成函数(母函数)详解
  • 原文地址:https://www.cnblogs.com/shayue/p/pan-bie-shu-zi-tu-pian-neng-fou-yi-bi-wan-cheng.html
Copyright © 2011-2022 走看看