zoukankan      html  css  js  c++  java
  • UVA 10085 The most distant state

    UVA_10085

    这个题目和八数码问题基本是一样的,只不过八数码问题是求变成指定图形所需的最少步骤,而这个问题是从指定图形出发,去找一个图形使得其按少步骤操作以得到指定图形所需的步骤是所有图形中最多的。

    从代码的角度讲,八数码问题的广搜的while循环是在遇到指定图形时退出的,而这个问题的while循环只能是在front=rear时退出,这样才算搜完了所有情况。

    对于八数码问题的相关知识可以参考刘汝佳白书的P132

    #include<stdio.h>
    #include
    <string.h>
    #define HASH 100003
    int st[1000000][9],fa[1000000],move[1000000];
    int head[1000003],next[1000000];
    int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
    int hash(int *p)
    {
    int i,v;
    v
    =0;
    for(i=0;i<9;i++)
    v
    =v*10+p[i];
    return v%HASH;
    }
    int insert(int k)
    {
    int i,h;
    h
    =hash(st[k]);
    for(i=head[h];i!=-1;i=next[i])
    if(memcmp(st[i],st[k],sizeof(st[k]))==0)
    break;
    if(i==-1)
    {
    next[k]
    =head[h];
    head[h]
    =k;
    return 1;
    }
    else
    return 0;
    }
    void printpath(int k)
    {
    if(fa[k]==-1)
    return;
    printpath(fa[k]);
    if(move[k]==0)
    printf(
    "U");
    else if(move[k]==1)
    printf(
    "D");
    else if(move[k]==2)
    printf(
    "L");
    else
    printf(
    "R");
    }
    int main()
    {
    int i,j,k,temp,t,tt;
    int front,rear,x,y,z,newx,newy,newz;
    scanf(
    "%d",&t);
    for(tt=0;tt<t;tt++)
    {
    front
    =rear=0;
    for(i=0;i<3;i++)
    for(j=0;j<3;j++)
    scanf(
    "%d",&st[rear][i*3+j]);
    fa[rear]
    =move[rear]=-1;
    memset(head,
    -1,sizeof(head));
    insert(rear);
    rear
    ++;
    while(front<rear)
    {
    for(z=0;z<9;z++)
    if(st[front][z]==0)
    break;
    x
    =z/3;
    y
    =z%3;
    for(i=0;i<4;i++)
    {
    memcpy(st[rear],st[front],
    sizeof(st[front]));
    newx
    =x+dx[i];
    newy
    =y+dy[i];
    if(newx>=0&&newx<3&&newy>=0&&newy<3)
    {
    newz
    =newx*3+newy;
    temp
    =st[rear][z];
    st[rear][z]
    =st[rear][newz];
    st[rear][newz]
    =temp;
    if(insert(rear))
    {
    fa[rear]
    =front;
    move[rear]
    =i;
    rear
    ++;
    }
    }
    }
    front
    ++;
    }
    printf(
    "Puzzle #%d\n",tt+1);
    for(i=0;i<9;i++)
    {
    if(i%3!=0)
    printf(
    " ");
    printf(
    "%d",st[rear-1][i]);
    if((i+1)%3==0)
    printf(
    "\n");
    }
    printpath(rear
    -1);
    printf(
    "\n\n");
    }
    return 0;
    }

      

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/staginner/p/2173799.html
Copyright © 2011-2022 走看看