hdu 1430+hdu 3567(预处理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430
思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状态标号做相应的修改,先预处理出12345678到所有状态的路径,记录所有状态的pre值,直接输出即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<string> 7 using namespace std; 8 9 struct Node{ 10 char str[11]; 11 Node(){}; 12 Node(char _str[]){ 13 for(int i=0;i<8;i++){ 14 str[i]=_str[i]; 15 } 16 } 17 }; 18 19 int fac[]={1,1,2,6,24,120,720,5040,40320}; 20 int Get_Hash(Node &p) 21 { 22 int val=0; 23 for(int i=0;i<8;i++){ 24 int cnt=0; 25 for(int j=0;j<i;j++){ 26 if(p.str[j]>p.str[i])cnt++; 27 } 28 val+=cnt*fac[i]; 29 } 30 return val; 31 } 32 33 void Move_A(Node &p) 34 { 35 reverse(p.str,p.str+8); 36 } 37 38 void Move_B(Node &p) 39 { 40 char ch=p.str[3]; 41 for(int i=3;i>=1;i--)p.str[i]=p.str[i-1]; 42 p.str[0]=ch; 43 ch=p.str[4]; 44 for(int i=4;i<=6;i++)p.str[i]=p.str[i+1]; 45 p.str[7]=ch; 46 } 47 48 void Move_C(Node &p) 49 { 50 swap(p.str[1],p.str[2]); 51 swap(p.str[5],p.str[6]); 52 swap(p.str[1],p.str[5]); 53 } 54 55 56 int pre[400000],ans[400000]; 57 bool mark[400000]; 58 59 void BFS() 60 { 61 queue<Node>que; 62 que.push(Node("12345678")); 63 memset(mark,false,sizeof(mark)); 64 mark[0]=true; 65 while(!que.empty()){ 66 Node p=que.front(); 67 que.pop(); 68 int p_val=Get_Hash(p); 69 Node q(p); 70 Move_A(q); 71 int q_val=Get_Hash(q); 72 if(!mark[q_val]){ 73 mark[q_val]=true; 74 pre[q_val]=p_val; 75 ans[q_val]='A'; 76 que.push(q); 77 } 78 q=p; 79 Move_B(q); 80 q_val=Get_Hash(q); 81 if(!mark[q_val]){ 82 mark[q_val]=true; 83 pre[q_val]=p_val; 84 ans[q_val]='B'; 85 que.push(q); 86 } 87 q=p; 88 Move_C(q); 89 q_val=Get_Hash(q); 90 if(!mark[q_val]){ 91 mark[q_val]=true; 92 pre[q_val]=p_val; 93 ans[q_val]='C'; 94 que.push(q); 95 } 96 } 97 } 98 99 char S[11],T[11]; 100 int SS[11]; 101 int main() 102 { 103 BFS(); 104 while(~scanf("%s%s",S,T)){ 105 for(int i=0;i<8;i++)SS[S[i]-'1']=i; 106 for(int i=0;i<8;i++)T[i]=SS[T[i]-'1']+'1'; 107 Node p=Node(T); 108 int val=Get_Hash(p); 109 string ss=""; 110 while(val){ 111 ss+=ans[val]; 112 val=pre[val]; 113 } 114 reverse(ss.begin(),ss.end()); 115 cout<<ss<<endl; 116 } 117 return 0; 118 } 119 120 121 122 123 124 125 126 127 128 129 130
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567
思路:因为这题有一个特殊的点X,所以枚举X的位置,打出9张前驱表,用魔板题一样的方法将两个状态的对应标号转化,输出就好了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 9 struct Node{ 10 int map[3][3]; 11 int x,y; 12 Node(){} 13 Node(char *str){ 14 for(int i=0,xx=0,yy=0;str[i];i++){ 15 map[xx][yy]=str[i]; 16 if(str[i]=='X'){ x=xx,y=yy; } 17 yy++; 18 if(yy==3)xx++,yy=0; 19 } 20 } 21 }S; 22 23 int fac[]= {1,1,2,6,24,120,720,5040,40320}; 24 //康拓展开 25 int Get_Hash(Node &p) 26 { 27 char str[11]; 28 int val=0; 29 for(int i=0;i<3;i++){ 30 for(int j=0;j<3;j++){ 31 str[i*3+j]=p.map[i][j]; 32 int cnt=0; 33 for(int k=i*3+j-1;k>=0;k--){ 34 if(str[k]>str[i*3+j])cnt++; 35 } 36 val+=fac[i*3+j]*cnt; 37 } 38 } 39 return val; 40 } 41 42 int dir[4][2]={{1,0},{0,-1},{0,1},{-1,0}}; 43 char Dir[5]="dlru"; 44 int pre[11][400000]; 45 char ans[11][400000]; 46 bool mark[400000]; 47 48 void bfs(int x) 49 { 50 memset(pre[x],-1,sizeof(pre[x])); 51 memset(mark,false,sizeof(mark)); 52 queue<Node>que; 53 que.push(S); 54 mark[Get_Hash(S)]=true; 55 while(!que.empty()){ 56 Node p=que.front(); 57 que.pop(); 58 int p_val=Get_Hash(p); 59 for(int i=0;i<4;i++){ 60 Node q=p; 61 q.x=p.x+dir[i][0],q.y=p.y+dir[i][1]; 62 if(q.x<0||q.x>=3||q.y<0||q.y>=3)continue; 63 q.map[p.x][p.y]=q.map[q.x][q.y]; 64 q.map[q.x][q.y]='X'; 65 int q_val=Get_Hash(q); 66 if(mark[q_val])continue; 67 mark[q_val]=true; 68 pre[x][q_val]=p_val; 69 ans[x][q_val]=Dir[i]; 70 que.push(q); 71 } 72 } 73 } 74 75 char str[11]; 76 int num[11]; 77 int main() 78 { 79 S=Node("X12345678"); 80 bfs(0); 81 S=Node("1X2345678"); 82 bfs(1); 83 S=Node("12X345678"); 84 bfs(2); 85 S=Node("123X45678"); 86 bfs(3); 87 S=Node("1234X5678"); 88 bfs(4); 89 S=Node("12345X678"); 90 bfs(5); 91 S=Node("123456X78"); 92 bfs(6); 93 S=Node("1234567X8"); 94 bfs(7); 95 S=Node("12345678X"); 96 bfs(8); 97 98 int _case,p,t=1; 99 scanf("%d",&_case); 100 while(_case --){ 101 scanf("%s", str); 102 for(int i = 0, j = 0; i <= 8; i ++ ){ 103 if(str[i] != 'X') num[str[i] - '0'] = j ++; 104 else p = i; 105 } 106 scanf("%s", str); 107 for(int i=0;i<=8;i++){ 108 if(str[i]=='X')continue; 109 str[i]=num[str[i]-'0']+'1'; 110 } 111 S=Node(str); 112 int val=Get_Hash(S); 113 string ss=""; 114 while(val!=-1){ 115 ss+=ans[p][val]; 116 val=pre[p][val]; 117 } 118 reverse(ss.begin(), ss.end()); 119 printf("Case %d: %d\n",t++,ss.size()-1); 120 for(int i=1;i<ss.size();i++)cout<<ss[i]; 121 cout<<endl; 122 } 123 return 0; 124 }