您的位置:首页 > 其它

hdoj1043,eight

2015-09-08 08:10 363 查看
1.首先写一下用广搜预处理得到的。这个方法耗时有点大。但是可以通过。

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

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

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

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

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

/*

content: hdoj1043,找错版本,找到错误,这是正确的答案。
time : 2015/09/08
author : kaka

1.看来路径是反的不仅仅指的是顺序,连方向都是。
2.为什么这样找到的事最短的呢?用的是广搜。这是保证。否则深搜就不行。

*/

#include<queue>
#include<iostream>
#include<string>
using namespace std;
#define MAXN 362885
const int N = 9;
struct point
{
char map
;
int position;
string step;
};
//记录路径的数列
string inversionPath[MAXN];
//康托序列
int fac
={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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm hdoj 广搜 康托序列