分析
这题看到整个矩阵只有16个数,且都是0/1,所以考虑用一个16位二进制数来存整个状态。然后用一个数组就可以存所有的状态(判断是否曾经到达)
我们从(3,3)开始枚举每个点,从开始状态开始搜索。矩阵的坐标是这样设计的:
3 2 1 0
3
2
1
0
每次都判断能否向下或者向右交换(数字不一样且状态没访问过),能访问就入队。记录前驱和坐标,后面递归输出。
关于二维与一维的转换和一些位运算解析:
1. pos=4*i+j;//在16位中的位置
2. q[h]&(1<<pos)//取出第pos位
3. temp=q[h]^(3<<pos-1)//将自己和右边的交换
4. temp=q[h]^((1<<pos)+(1<<pos-4))//将自己和下面的交换
5. p1[q[t]]=(5-(i+1))*10+(5-(j+1));
p2[q[t]]=(5-(i+1))*10+(5-(j+1)+1);//转为横纵坐标的记录
其实在存状态是否被访问的时候,还可以再压缩,现在是一个整数存一个“能或不能”,其实可以一位存一个,又压缩到1/32了,但是较难实现,我没有使用。
瞎扯淡:今天早上调了好久,下午睡一觉过来打了不到30min过了样例,很兴奋,小心翼翼又试了很多次,结果洛谷一次过,差点跳起来!
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;