UVA 10085 The most distant state

 

大意:八数码问题的变形,让你求离当前状态最远的距离。

思路:BFS + hash判重,直到不能扩展为止,最后一个节点一定是最远的距离(由BFS性质知道)

CODE:

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include < set>
using  namespace std;


typedef  int State[ 9];
const  int MAXN =  1000003;
const  int dx[] = {- 1, 1, 0, 0};
const  int dy[] = { 0, 0,- 1, 1};
char dir[ 5] =  " UDLR ";

State st[MAXN];
int fa[MAXN], path[MAXN];      // 存储路径 
int first[MAXN], next[MAXN];
State state;

int ans;

void init()
{
    memset(first, - 1sizeof(first));
    memset(fa,  0sizeof(fa));
    memset(path,  0sizeof(path));
}

int hash(State &s)  // 映射 
{
     int v =  0;
     for( int i =  0; i <  9; i++) v = v* 10 + s[i];
     return v%MAXN;
}

int try_to_insert( int s)    // hash判重 
{
     int h = hash(st[s]);
     for( int v = first[h]; v!=- 1; v = next[v])
    {
         if(memcmp(st[v], st[s],  sizeof(st[s])) ==  0return  0;
    }
    next[s] = first[h];
    first[h] = s;
     return  1;
}

int check( int r,  int c)
{
     if(r >=  0 && r <  3 && c >=  0 && c <  3)     return  1;
      return  0;
}

void bfs()
{
    init();
     int front =  0, rear =  1;
    fa[ 0] = path[ 0] = - 1;
    try_to_insert( 0);
     while(front < rear)
    {
        State& s = st[front];
         int z;
         for(z =  0; z <  9; z++)  if(!s[z])  break;
         int x = z/ 3, y = z% 3;
         for( int i =  0; i <  4; i++)
        {
             int newx = x + dx[i];
             int newy = y + dy[i];
             int newz =  3*newx + newy;
             if(check(newx, newy))
            {
                State& t = st[rear];
                memcpy(&t, &s,  sizeof(s));
                t[newz] = s[z];
                t[z] = s[newz];
                 if(try_to_insert(rear))
                {
                    fa[rear] = front;
                    path[rear] = i;
                    rear++;
                }
            }
        }
        front++;
    }
    ans = rear- 1;
}

void print_path( int cur)  // 递归打印路径 
{
     if(cur)
    {
        print_path(fa[cur]);
        printf( " %c ", dir[path[cur]]);
    }
}

int main()
{
     int T, times =  0;
    scanf( " %d ", &T);
     while(T--)
    {
         for( int i =  0; i <  9; i++)    scanf( " %d ", &st[ 0][i]);
        bfs();
        printf( " Puzzle #%d\n ", ++times);
         for( int i =  0; i <  3; i++)
        {
            printf( " %d %d %d ", st[ans][ 3*i], st[ans][ 3*i+ 1], st[ans][ 3*i+ 2]);
            printf( " \n ");
        }
        print_path(ans);
        printf( " \n\n ");
    }
     return  0;
}

 

你可能感兴趣的:(ant)