hdoj1043,eight

来源:互联网 发布:ug8.0编程教程 编辑:程序博客网 时间:2024/06/02 09:30

1.首先写一下用广搜预处理得到的。这个方法耗时有点大。但是可以通过。

2.主要用了广搜和倒序输出路径。当然,这里的struct比较特殊。需要好好体会。

3.主要问题是,注意良好的编程习惯。我就是两个变量搞混了,导致一直出错。

4.这里借助广搜,因为广搜搜出来的就是最短的了。而深搜就不行。

5.还有就是康拓序列了。这个需要记住了,觉得用的很多。小心正确的顺序康托序列是0;

6.加入1234,计算4231的康托序列,就是看比第一个4小的数有几个就乘以康拓序列的地4位。这是因为类似排列组合,以1,2,3开头的序列数。后面类似。

/*content:  hdoj1043,找错版本,找到错误,这是正确的答案。time   :  2015/09/08author :  kaka1.看来路径是反的不仅仅指的是顺序,连方向都是。2.为什么这样找到的事最短的呢?用的是广搜。这是保证。否则深搜就不行。*/#include<queue>#include<iostream>#include<string>using namespace std;#define MAXN  362885const int N = 9;struct point{char map[N];int position;string step;};//记录路径的数列string inversionPath[MAXN];//康托序列int fac[N]={1, 1, 2, 6, 24, 120, 720, 5040, 40320};//标记是不是这个序列已经有了。bool visited[MAXN];//看清楚,这里所有的方向都是反的const int dir[4][2] = {1,0,0,1,-1,0,0,-1};const char option[4] = {'u','l','d','r'};//对特定序列计算康托数int computeCan(point p);//广搜bool bfs();int cantor(point p){int result=0;for ( int i = 0;i < N; i++ ){int ans = 0;for ( int j = i+1;j < N;j++){if(p.map[i]>p.map[j])ans++;}//计算已知序列是总数里的第几个。根据第一个数,第二个一次计算。result+=fac[8-i]*ans;}return result;}bool bfs(){queue<point> que;point p;for ( int i = 0; i < N-1; i++){p.map[i] = i+1+'0';}visited[0]=true;p.map[N-1] = 'x';p.position = 8;p.step ="";que.push(p);while(!que.empty()){point nowPoint = que.front();que.pop();int num = nowPoint.position;for (int i = 0; i < 4; i++){int row = num/3+dir[i][0];int col = num%3+dir[i][1];//if(row>=0&&row<3&&col>=0&&col<3)if(row>=0&&row<3&&col>=0&&col<3){//换上这个不出现两个x//p和nowpoint弄混,以后一定要注意//为什么不重载就可以用这种构造函数point nextPoint(nowPoint);        nextPoint.map[nextPoint.position]=nextPoint.map[row*3+col];        nextPoint.position=row*3+col;        nextPoint.map[nextPoint.position]='x';int cantorTemp = cantor(nextPoint);if(visited[cantorTemp])continue;visited[cantorTemp]=true;nextPoint.step+=option[i];inversionPath[cantorTemp]=nextPoint.step;que.push(nextPoint);}}}return false;}int main(){point startPoint;int cantorNum;bfs();while(cin>>startPoint.map[0]){if(startPoint.map[0]=='x')startPoint.position=0;for(int i=1;i<9;i++)            {              cin>>startPoint.map[i];              if(startPoint.map[i]=='x')                  startPoint.position=i;          }  cantorNum = cantor(startPoint);if(visited[cantorNum]){for ( int i = inversionPath[cantorNum].size()-1; i>=0;i--)cout << inversionPath[cantorNum][i];cout << endl;}else { cout<<"unsolvable"<<endl; }}return 0;}



0 0