题目链接:点击打开链接
事情是这样的,我先在TLE无数发之后A了POJ的1077,然后在VJ上看到“原题”,然而,此原题被我TLE5发MLE9发,最后从学长那里学得记录路径的方法之后才过,却原来,这道所谓原题并非原题!!!HDU 的1043和POJ的1077都叫Eight,但是由于HDU上是多组数据POJ上单组,所以POJ上直接正常bfs搜索, HDU上则需要预处理。。。
方法是一样的,对于输入的串,保存成数组,其中x的位置用0代替,最终目标就是123456780
o对了,哈希用的康拓展开,所以12356780对应的康拓展开值是46234
然后正常bfs搜索就好,不过由于时间卡的很死,对于POJ的1077据说双向bfs会更快
然后,HDU的内存不愿多说,MLE之后换了个记录路径的方法
具体见代码:
poj 1077:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stdlib.h>
#include<cctype>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int ans = 46234;//123456780
int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int ct (int s[])
{
int sun = 0, tmp;
for (int i = 0; i < 9; i++)
{
tmp = 0;
for (int j = i + 1; j < 9; j++)
if (s[j] < s[i]) tmp++;
sun += (tmp * fac[9 - i - 1]);
}
return sun + 1;
}
bool vis[400000];
struct Node
{
int g[10];
int x;
int st;
string p;
} h;
const int dx[] = { -1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
char dd[] = {'u', 'd', 'l', 'r'};
string path;
void bfs()
{
queue<Node>q;mem(vis,0);
q.push (h);
// vis[h.st] = 1;
while (!q.empty() )
{
h = q.front();
q.pop();
if (h.st == ans)
{
path = h.p;
return;
}
int x = h.x / 3;
int y = h.x % 3;
for (int i = 0; i < 4; ++i)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 && yy >= 0 && xx < 3 && yy < 3)
{
Node nx = h;
nx.x = xx * 3 + yy;
swap (nx.g[h.x], nx.g[nx.x]);
nx.st = ct (nx.g);
if (!vis[nx.st])
{
if (nx.st == ans)
{
path = nx.p + dd[i];
return;
}
vis[nx.st] = 1;
nx.p += dd[i];
q.push (nx);
}
}
}
}
}
int main()
{
char tmp;
while (~scanf("%c",&tmp))
{
if (tmp == 'x')
{
h.g[0] = 0;
h.x = 0;
}
else h.g[0] = tmp-48;
for (int i = 1; i < 9; ++i)
{
scanf(" %c",&tmp);
if (tmp == 'x')
{
h.g[i] = 0;
h.x = i;
}
else h.g[i] = tmp - 48;
}
getchar();
h.st = ct (h.g);
h.p.clear();
path = "unsolvable";
bfs();
cout<<path<<endl;
}
return 0;
}
HDU 1043:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stdlib.h>
#include<cctype>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};//上下左右
const char dd[] = "durl";
const int ans = 46234;//123456780
int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int ct (int s[])
{
int sun = 0, tmp;
for (int i = 0; i < 9; i++)
{
tmp = 0;
for (int j = i + 1; j < 9; j++)
if (s[j] < s[i]) tmp++;
sun += (tmp * fac[9 - i - 1]);
}
return sun + 1;
}
struct Node
{
int g[10];
int x;
int st;
}h;
struct No
{
int fa;
char mo;
}moo[400000];
bool vis[400000];
void bfs()
{
queue<Node>q;
q.push(h);
vis[h.st] = 1;
while (!q.empty())
{
h = q.front();q.pop();
int x = h.x / 3;
int y = h.x % 3;
for (int i = 0; i < 4; ++i)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 && yy >= 0 && xx < 3 && yy < 3)
{
Node nx = h;
nx.x = xx * 3 + yy;
swap (nx.g[h.x], nx.g[nx.x]);
nx.st = ct (nx.g);
if (!vis[nx.st])
{
vis[nx.st] = 1;
moo[nx.st].mo = dd[i];
moo[nx.st].fa = h.st;
q.push (nx);
}
}
}
}
}
void init()
{
for (int i = 0;i < 8;++i) h.g[i] = i+1;
h.g[8] = 0;
h.x = 8;
h.st = ans;
moo[ans].fa = -1;
bfs();
}
int main()
{
char tmp;init();int s[10];
while (cin>>tmp)
{
if (tmp == 'x') s[0] = 0;
else s[0] = tmp - 48;
for (int i = 1;i < 9;++i)
{
cin>>tmp;
if(tmp == 'x') s[i] = 0;
else s[i] = tmp - 48;
}
int st = ct (s);
if (st == ans)
{
puts("");
continue;
}
if (!vis[st]) printf("unsolvable\n");
else
{
while (moo[st].fa!=-1)
{
printf("%c",moo[st].mo);
st = moo[st].fa;
}
puts("");
}
}
return 0;
}