hdu 3567 康托展开 +BFS
2017-11-02 19:50
330 查看
HDU 1430 DFS + 康托展开 + 映射处理 +预处理!
http://blog.csdn.net/little_boy_z/article/details/78428300
和hdu1430很类似,模仿着来即可。
主要会用康托就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1000000005
using namespace std;
int ed;
int fac[3][3]= {{1,1,2},{6,24,120},{720,5040,40320}};//计算康拓值
struct node
{
int Map[3][3];
int x,y;
int Hash;
bool cheak()
{
if(x>=0&&x<3&&y>=0&&y<3)
return true ;
return false ;
}
} u,uu,v;
int vis[9][400000];//标记
int pri[9][400000];//路径
int dir[4][2]= {{1,0},{0,-1},{0,1},{-1,0}};
int get_hash(int maze[3][3]) //计算康拓值
{
int ret=0;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
int cnt=0;
for(int a=0; a<i; a++)
for(int b=0; b<3; b++)
if(maze[a][b]>maze[i][j])
cnt++;
for(int b=0; b<j; b++)
if(maze[i][b]>maze[i][j])
cnt++;
ret+=cnt*fac[i][j];
}
return ret;
}
char ch[5]= {"dlru"};
//输出路径
void print(int i)
{
int st=ed;
int cnt=0,ans[1000];
while(pri[i][st]!=-2)
{
ans[cnt++]=vis[i][st];
st=pri[i][st];
}
printf("%d\n",cnt);
for(int i=cnt-1; i>=0; i--)
printf("%c",ch[ans[i]]);
printf("\n");
return ;
}
void bfs(int kind)
{
queue<node>que;
que.push(u);
pri[kind][u.Hash]=-2;
while(!que.empty())
{
uu=que.front();
que.pop();
for(int i=0; i<4; i++)
{
v=uu;
v.x+=dir[i][0];
v.y+=dir[i][1];
if(v.cheak())
{
swap(v.Map[v.x][v.y],v.Map[uu.x][uu.y]);
v.Hash=get_hash(v.Map);
if(pri[kind][v.Hash]==-1)
{
pri[kind][v.Hash]=uu.Hash;
vis[kind][v.Hash]=i;
que.push(v);
}
}
}
}
}
void Init(char *str,int kind)
{
int k=0;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
if(str[k]=='X')
u.Map[i][j]=0;
else
u.Map[i][j]=str[k]-'0';
k++;
}
u.x=kind/3;
u.y=kind%3;
u.Hash=get_hash(u.Map);
bfs(kind);
}
int main()
{
int t;
int tt=1;
//预处理
memset(pri,-1,sizeof(pri));
Init("X12345678",0);
Init("1X2345678",1);
Init("12X345678",2);
Init("123X45678",3);
Init("1234X5678",4);
Init("12345X678",5);
Init("123456X78",6);
Init("1234567X8",7);
Init("12345678X",8);
scanf("%d",&t);
while(t--)
{
char s1[10],s2[10];
scanf("%s%s",s1,s2);
int a[3][3],b[3][3],pos,c[9],k=1;
for(int i=0; i<9; i++)
{
if(s1[i]=='X')
{
c[0]=0;
pos=i;
}
else
c[s1[i]-'0']=k++;
}
for(int i=0; i<9; i++)
b[i/3][i%3]=(s2[i]=='X'?c[0]:c[s2[i]-'0']);
ed=get_hash(b);
printf("Case %d: ",tt++);
print(pos);
}
return 0;
}
http://blog.csdn.net/little_boy_z/article/details/78428300
和hdu1430很类似,模仿着来即可。
主要会用康托就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<string>
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 1000000005
using namespace std;
int ed;
int fac[3][3]= {{1,1,2},{6,24,120},{720,5040,40320}};//计算康拓值
struct node
{
int Map[3][3];
int x,y;
int Hash;
bool cheak()
{
if(x>=0&&x<3&&y>=0&&y<3)
return true ;
return false ;
}
} u,uu,v;
int vis[9][400000];//标记
int pri[9][400000];//路径
int dir[4][2]= {{1,0},{0,-1},{0,1},{-1,0}};
int get_hash(int maze[3][3]) //计算康拓值
{
int ret=0;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
int cnt=0;
for(int a=0; a<i; a++)
for(int b=0; b<3; b++)
if(maze[a][b]>maze[i][j])
cnt++;
for(int b=0; b<j; b++)
if(maze[i][b]>maze[i][j])
cnt++;
ret+=cnt*fac[i][j];
}
return ret;
}
char ch[5]= {"dlru"};
//输出路径
void print(int i)
{
int st=ed;
int cnt=0,ans[1000];
while(pri[i][st]!=-2)
{
ans[cnt++]=vis[i][st];
st=pri[i][st];
}
printf("%d\n",cnt);
for(int i=cnt-1; i>=0; i--)
printf("%c",ch[ans[i]]);
printf("\n");
return ;
}
void bfs(int kind)
{
queue<node>que;
que.push(u);
pri[kind][u.Hash]=-2;
while(!que.empty())
{
uu=que.front();
que.pop();
for(int i=0; i<4; i++)
{
v=uu;
v.x+=dir[i][0];
v.y+=dir[i][1];
if(v.cheak())
{
swap(v.Map[v.x][v.y],v.Map[uu.x][uu.y]);
v.Hash=get_hash(v.Map);
if(pri[kind][v.Hash]==-1)
{
pri[kind][v.Hash]=uu.Hash;
vis[kind][v.Hash]=i;
que.push(v);
}
}
}
}
}
void Init(char *str,int kind)
{
int k=0;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
if(str[k]=='X')
u.Map[i][j]=0;
else
u.Map[i][j]=str[k]-'0';
k++;
}
u.x=kind/3;
u.y=kind%3;
u.Hash=get_hash(u.Map);
bfs(kind);
}
int main()
{
int t;
int tt=1;
//预处理
memset(pri,-1,sizeof(pri));
Init("X12345678",0);
Init("1X2345678",1);
Init("12X345678",2);
Init("123X45678",3);
Init("1234X5678",4);
Init("12345X678",5);
Init("123456X78",6);
Init("1234567X8",7);
Init("12345678X",8);
scanf("%d",&t);
while(t--)
{
char s1[10],s2[10];
scanf("%s%s",s1,s2);
int a[3][3],b[3][3],pos,c[9],k=1;
for(int i=0; i<9; i++)
{
if(s1[i]=='X')
{
c[0]=0;
pos=i;
}
else
c[s1[i]-'0']=k++;
}
for(int i=0; i<9; i++)
b[i/3][i%3]=(s2[i]=='X'?c[0]:c[s2[i]-'0']);
ed=get_hash(b);
printf("Case %d: ",tt++);
print(pos);
}
return 0;
}
相关文章推荐
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
- HDU 3567 Eight II 预处理+bfs+hash
- ACM-康托展开+预处理BFS之魔板——hdu1430
- HDU 3567 Eight II 八数码(2)
- hdu 3567 Eight II 八数码 双向BFS
- HDU 3567 Eight II BFS预处理
- HDU 1043 Eight(康托展开)
- HDU 1043 搜索+康托展开
- HDU 3567 Eight II
- hdu 1430+hdu 3567(预处理)
- HDU 3567
- hdu1043 Eight(A*/双向BFS/单项BFS打表+康托展开)
- hdu 1043 eight (搜索 + 康托展开)
- 【HDU - 1429】胜利大逃亡(续) 【状态压缩+BFS】
- HDU 3567 Eight II
- HDU 1043 Eight (BFS·八数码·康托展开)
- HDU 1043 Eight (BFS·八数码·康托展开)
- HDU 3567 Eight II
- POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
- (多回顾)hdu 3567 Eight2 (bfs逆处理+打表+映射+康托压缩~)