1426. Sudoku Killer(HDU)

题意理解

数独问题: 9×9数独,实现自动填数。输入格式要求是空行相隔,输出格式也是空行相隔,(其他条件理解简单就不重复)

问题分析

用dfs搜索

数独玩过,大致规则就是一个dfs搜索,每个空位有多个可选值,确定值后填下一个空位,如果下个空位无值可填,就回滚到上一个空位,填成新的值,直到所有值都填成功。

确定搜索空间为空位,以整个数独为空间非常大不合适,用vector,元素为横纵坐标的结构体。

确定验证空位值条件,要求横行、竖行数字不重复,小范围(9×9分为3×3个小范围)内数字不重复,横竖行容易,遍历9个位置,如果和填值一样就无效;小范围计算左上角点(i/3*3),然后加3的步长即可。

非递归遍历算法思路,遍历空位点序列,对于当前空位点,校验1-9中有效值,放入栈中,如果有有效值,弹栈,填充当前空位,否则,执行回滚,弹栈,如果当前空位比栈顶元素序号大1,直接修改数独栈顶元素序号空位值;否则,当前空位比栈顶元素序号大很多,循环清空栈顶元素序号数独的空位值,再弹栈,直到修改数独栈顶元素序号空位值结束。

对于输入的处理,此题输入是一个矩阵,方法是循环输入字符,设定行列坐标i和j,如果字符是1到9,设定a[i][j]的值为字符-'0';如果字符是?,设定a[i][j]为0,并放到搜索空间vector中。如果j为9,就表示一行输入完成换行;如果i为9,就表示矩阵输入完成,进行dfs搜索,为了支持多个矩阵处理,需要重置i,j为0。

对于输出的处理,输出是在输入的i为9中来处理,当矩阵输入完成,第一次输出前不需要加空行,第二次就需要加空行,否则失败。

其他

深度遍历搜索不一定是在树结构,也不一定是在图结构,也不一定要在类似于图或树的结构上处理,只要设定搜索空间,搜索结果验证方法,搜索终止条件等就可以用深度遍历。

非递归和递归考虑的不同,递归简单一些,非递归可以看出把递归的栈手动来实现了。

对于复杂程序调试,因为输入复杂,输出也复杂,控制台调试不够用了,需要新的方法处理

freopen("1.txt", "r", stdin); freopen("2.txt", "w", stdout); 用完注释掉就可以了,这是好东西。!

一共19次,从2018-11-07 13:26:20 到 2019-01-02 15:18:17 历时 56天 1时 51分 57秒,这是我做过的最长时间的一道题。

前后做了半年了,一直超时,如果这题我一直超时,那么我的算法之路就到此为止。我会做题,直到ac。期间不会再刷其他的题。

2019/1/2 终于ac了,问题是计算输出是,第一次输出数独结果不需要前置空行,后面处理每次需要前置空行。我的错误是第一次输出数独结果也加空行了。也就是说我的非递归算法和递归算法也是可以的。一直超时的原因是,如果遍历算法不对,那么会在搜索空间来回游走,退不出来,如果输出需要空行间隔,他会等待空行。

2019/1/1 题例可以解决,但是换了一个例子就超时,检查发现设计的算法会很久,反复修改空位值

2018/12/30 重新设计dfs算法,这次考虑从空位入手,将空位当成搜索对象处理。样例可以解决,但是跑超时

2018/10 按照棋盘为搜索对象,dfs搜索发现超时,更新校验方法,无效。

链接

https://github.com/xierensong/learngit/tree/master/hdu/1426

猜你喜欢

转载自blog.csdn.net/xiexie1357/article/details/85567083
今日推荐