POJ1077 Eight —— 经典的搜索问题

题目链接:http://poj.org/problem?id=1077



Eight
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 33267 Accepted: 14404 Special Judge

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as: 
 1  2  3  4 

 5  6  7  8 

 9 10 11 12 

13 14 15  x 

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle: 
 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 

 5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8 

 9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12 

13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x 

           r->           d->           r-> 

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively. 

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course). 

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
arrangement. 

Input

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle 
 1  2  3 

 x  4  6 

 7  5  8 

is described by this list: 
 1 2 3 x 4 6 7 5 8 

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr

Source




题解:

1.对于棋盘,所有的情况为:9! <4e5<1e6,所以使用枚举的方法是不会超时的,前提是数据较弱(如POJ1077),或者一次性枚举预处理掉所有情况(HDU1043)。

2.对于判重:使用STL的set肯定会超时的。一开始想利用十进制数,每一位保存一个格子,结果9个格子就是9位数,数组根本开不了那么大,所以此种尝试失败。后来看到康拓,不太理解为什么能用(不会用冲突吗?),但还是先用着,有时间再研究一下。如果下次遇到类似123456789这九个数需要进行哈希的,就使用康拓试试。

3.推荐阅读:八数码的八境界   ——  来自liugoodness,特此鸣谢。



写法:

1.正向BFS:http://blog.csdn.net/dolfamingo/article/details/77855338

2.反向BFS:http://blog.csdn.net/dolfamingo/article/details/77855373

3.双向BFS: http://blog.csdn.net/dolfamingo/article/details/77855491
4.  A*算法  : http://blog.csdn.net/dolfamingo/article/details/77855498

5.IDA*算法:http://blog.csdn.net/dolfamingo/article/details/77855518

### 解决方案概述 对于 POJ 1009 Edge Detection 的问题,核心在于实现一种基于邻域差异的边缘检测算法。具体来说,给定一个二维数组表示灰度图像,目标是计算每个像素点与其周围八个邻居之间的最大绝对差值,并以此作为新图像对应位置上的像素值。 #### 输入输出说明 程序接收多组测试数据,每组由两个整数 n 和 m 开始,分别代表矩阵的高度和宽度;随后跟着 n 行字符序列描述原始图片的内容。最终应打印出处理后的结果——即应用上述规则变换得到的新图形[^1]。 #### 关键逻辑解析 为了高效完成这项任务,可以采用如下策略: - **边界条件判断**:考虑到位于四角及边界的特殊单元格仅有部分有效邻居,在遍历过程中需特别注意这些情况下的索引范围控制。 - **双重循环结构**:通过嵌套迭代访问整个网格内的每一个元素,针对当前考察对象执行必要的运算操作并更新其对应的输出坐标处数值。 - **临时存储机制**:由于每次仅修改单个位置的数据而不影响其他待测样本,因此可利用额外的一维或二维辅助空间暂存中间状态直至一轮扫描结束再统一赋值回原位。 ```cpp #include <iostream> using namespace std; int main() { int cases; cin >> cases; while (cases--) { int rows, cols; char img[10][10]; cin >> rows >> cols; getchar(); // consume newline for(int i=0; i<rows; ++i){ gets(img[i]); } cout << "Test case #" << endl; for(int r=0;r<=rows;++r){ for(int c=0;c<=cols;++c){ bool isEdge=false; // Check all eight directions... if(r>0 && abs((int)(img[r-1][c]-'A')-(int)(img[r][c]-'A'))>=2) {isEdge=true;} if(c>0 && abs((int)(img[r][c-1]-'A')-(int)(img[r][c]-'A'))>=2) {isEdge=true;} if(r<rows&&abs((int)(img[r+1][c]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} if(c<cols&&abs((int)(img[r][c+1]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} if(r>0&&c>0&&abs((int)(img[r-1][c-1]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} if(r>0&&c<cols&&abs((int)(img[r-1][c+1]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} if(r<rows&&c>0&&abs((int)(img[r+1][c-1]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} if(r<rows&&c<cols&&abs((int)(img[r+1][c+1]-'A')-(int)(img[r][c]-'A'))>=2){isEdge=true;} putchar(isEdge ? '*' : ' '); } puts(""); } if (--cases >= 0) printf("\n"); } } ``` 这段 C++ 实现展示了如何读取输入、构建内部表示形式以及按照指定方式生成输出。值得注意的是,这里假设输入文件中的字母均处于大写区间内 ('A'-'Z'), 并据此进行了 ASCII 值比较来决定是否存在显著变化从而标记为边缘特征[*^3*].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值