zoukankan      html  css  js  c++  java
  • Poj 1077 Eight 八数码

    题目描述:求八数码的解,输出x的移动方式(输出步数最少的解,但是也可能会有多解,所以是special judge)

    如果判断8数码有没有解可以用逆序数求,找出规律即可求解

    解法一:搜索(没写过)

    解法二:康托展开,一种hash的方法。

    int try_to_insert(int s){
    int code = 0;
    for(int i=0;i<9;i++){
    int cnt=0;
    for(int j=i+1;j<9;j++){
    if(st[s][j]<st[s][i]) cnt++;
    }
    code += cnt*fact[8-i];
    }
    if(vis[code]==1) return 0;
    return vis[code] = 1;
    }

    如果简单的开一个数组,判重的时候后则需要开一个,则需要开一个九维的数组,一共会耗去99=387420789项,但其实0~8的排列只有9!=362880个,所以可以用一个hash表一一对应起来。

    解法3:A*(还不会)

    View Code
      1 Source Code
    2
    3 Problem: 1077 User: celia01
    4 Memory: 8920K Time: 141MS
    5 Language: G++ Result: Accepted
    6
    7 Source Code
    8 #include<iostream>
    9 #include<cstdio>
    10 #include<cmath>
    11 #include<cstring>
    12 #include<algorithm>
    13 #include<queue>
    14 #define see(x) cout<<#x<<":"<<x<<endl;
    15 using namespace std;
    16 typedef int State[9];
    17 const int MAXSIZE = 1000000;
    18 State st[MAXSIZE], goal;
    19
    20 const int dx[] = {0,-1,0,1};
    21 const int dy[] = {-1,0,1,0};
    22 bool vis[400000];
    23 int fact[9];
    24 int path[MAXSIZE];
    25 int pre[MAXSIZE];
    26 void init_lookup_table(){
    27 memset(vis,0,sizeof(vis));
    28 fact[0] = 1;
    29 for(int i=1;i<9;i++){
    30 fact[i] = fact[i-1]*i;
    31 }
    32 }
    33 int try_to_insert(int s){
    34 int code = 0;
    35 for(int i=0;i<9;i++){
    36 int cnt=0;
    37 for(int j=i+1;j<9;j++){
    38 if(st[s][j]<st[s][i]) cnt++;
    39 }
    40 code += cnt*fact[8-i];
    41 }
    42 if(vis[code]==1) return 0;
    43 return vis[code] = 1;
    44 }
    45
    46 int bfs(){
    47 init_lookup_table();
    48 int f=1, r=2;
    49 while(f<r){
    50 State& s = st[f];
    51
    52 if( memcmp(goal,s,sizeof(s)) == 0 ) return f;
    53 int z;
    54 for(z=0;z<9;z++) if(s[z]==0) break;
    55 int x=z/3, y=z%3;
    56 for(int d=0;d<4;d++){
    57 int newx = x+dx[d];
    58 int newy = y+dy[d];
    59 int newz = newx*3+newy;
    60 if(newx>=0&&newx<3&&newy>=0&&newy<3){
    61 State &t = st[r];
    62 memcpy(&t,&s,sizeof(s));
    63 t[newz] = s[z];
    64 t[z] = s[newz];
    65 pre[r] = f;
    66 path[r] = d;
    67 if(try_to_insert(r)) r++;
    68 }
    69 }
    70 f++;
    71 }
    72 return 0;
    73 }
    74
    75 void Path(int r){
    76 if(r<=1) return;
    77 Path(pre[r]);
    78 if(path[r]==0)
    79 printf("l");
    80 else if(path[r]==1)
    81 printf("u");
    82 else if(path[r]==2)
    83 printf("r");
    84 else
    85 printf("d");
    86 }
    87 int main(){
    88 int i, j, k, l;
    89 char ch[3];
    90 for(i=0;i<9;i++){
    91 scanf("%s",ch);
    92 if(ch[0]=='x'){
    93 st[1][i] = 0;
    94 }
    95 else st[1][i] = ch[0]-'0';
    96 goal[i]=i+1;
    97 }
    98 goal[8] = 0;
    99
    100 int ans = bfs();
    101 if(ans>0) Path(ans);
    102 else printf("-1");
    103 puts("");
    104 return 0;
    105 }
    View Code
      1 Source Code
    2
    3 Problem: 1077 User: celia01
    4 Memory: 12840K Time: 110MS
    5 Language: G++ Result: Accepted
    6
    7 Source Code
    8
    9
    10 #include<iostream>
    11 #include<cstdio>
    12 #include<cmath>
    13 #include<cstring>
    14 #include<algorithm>
    15 #include<queue>
    16 #define see(x) cout<<#x<<":"<<x<<endl;
    17 using namespace std;
    18 typedef int State[9];
    19 const int MAXSIZE = 1000000;
    20 State st[MAXSIZE], goal;
    21 int dist[MAXSIZE];
    22
    23 const int dx[] = {0,-1,0,1};
    24 const int dy[] = {-1,0,1,0};
    25 bool vis[400000];
    26 int fact[9];
    27 int path[MAXSIZE];
    28 int pre[MAXSIZE];
    29 void init_lookup_table(){
    30 memset(vis,0,sizeof(vis));
    31 memset(dist,0,sizeof(dist));
    32 fact[0] = 1;
    33 for(int i=1;i<9;i++){
    34 fact[i] = fact[i-1]*i;
    35 }
    36 }
    37 int try_to_insert(int s){
    38 int code = 0;
    39 for(int i=0;i<9;i++){
    40 int cnt=0;
    41 for(int j=i+1;j<9;j++){
    42 if(st[s][j]<st[s][i]) cnt++;
    43 }
    44 code += cnt*fact[8-i];
    45 }
    46 // see(vis[code])
    47 if(vis[code]==1) return 0;
    48 return vis[code] = 1;
    49 }
    50
    51 int bfs(){
    52 init_lookup_table();
    53 int f=1, r=2;
    54 while(f<r){
    55 //see(f) see(r)
    56 State& s = st[f];
    57
    58 if( memcmp(goal,s,sizeof(s)) == 0 ) return f;
    59 int z;
    60 for(z=0;z<9;z++) if(s[z]==0) break;
    61 int x=z/3, y=z%3;
    62 for(int d=0;d<4;d++){
    63 // system("pause");
    64 int newx = x+dx[d];
    65 int newy = y+dy[d];
    66 int newz = newx*3+newy;
    67 // see(z) see(newz)
    68 if(newx>=0&&newx<3&&newy>=0&&newy<3){
    69 State &t = st[r];
    70 memcpy(&t,&s,sizeof(s));
    71 t[newz] = s[z];
    72 t[z] = s[newz];
    73 // dist[r] = dist[f]+1;
    74 pre[r] = f;
    75 path[r] = d;
    76 if(try_to_insert(r)) r++;
    77 }
    78 }
    79 f++;
    80 // see(f)
    81 }
    82 return 0;
    83 }
    84
    85 void Path(int r){
    86 if(r<=1) return;
    87 Path(pre[r]);
    88 if(path[r]==0)
    89 printf("l");
    90 else if(path[r]==1)
    91 printf("u");
    92 else if(path[r]==2)
    93 printf("r");
    94 else
    95 printf("d");
    96 }
    97 int main(){
    98 int i, j, k, l;
    99 char ch[3];
    100 for(i=0;i<9;i++){
    101 scanf("%s",ch);
    102 if(ch[0]=='x'){
    103 st[1][i] = 0;
    104 }
    105 else st[1][i] = ch[0]-'0';
    106 goal[i]=i+1;
    107 }
    108 goal[8] = 0;
    109 // for(i=0;i<9;i++) cout<<st[1][i]; cout<<endl;
    110 // for(i=0;i<9;i++) cout<<goal[i]; cout<<endl;
    111
    112 int ans = bfs();//see(ans)
    113 if(ans>0) Path(ans);
    114 else printf("-1");
    115 puts("");
    116 return 0;
    117 }
  • 相关阅读:
    VS提示“项目文件" "已被重命名或已不在解决方案中”的解决办法 .
    微信公众平台教程和SDK收集
    “SQLServerAgent当前未运行”问题解决
    $(document).click() 在苹果手机上不能正常运行
    友盟iOS推送配置(从真机调试到推送)
    Ubuntu安装VMware Tools的方法
    TortoiseSVN客户端如何更改新的URL
    Windows Server 2008系统如何取消登录时要按Ctrl+Alt+Delete组合键
    Windows Server 2008 显示桌面图标
    用WinRAR进行安装包的制作
  • 原文地址:https://www.cnblogs.com/celia01/p/2435494.html
Copyright © 2011-2022 走看看