hdu 1430+hdu 3567(预处理)

来源:互联网 发布:声学模拟软件 编辑:程序博客网 时间:2024/06/05 22:33

题目链接: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     
View Code

题目链接: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 }
View Code

 

0 0