POJ 1184

题意:中文题,略。

题解:实际上原状态每个数在最后都对应着目标态相应位置,所以可以先通过不改变的移动达到相应位置,然后再增减数字得到目标态,这样bfs状态量就会一下降很多,6个数的排列也就6!,另外最后要求增减数字,所以光标必须到过那个地方,所以还需要一维记录光标到过的地方,由于光标移动受一定限制,所以最后只有10中光标访问位置的状态,即从6!排列中的一些光标状态中选出最优更改,事实证明,只有500多种状态。

View Code
  1 #include<cstdio>

  2 #include<cstring>

  3 #include<algorithm>

  4 using namespace std;

  5 const int N=10000;

  6 int sign[10][6]=

  7 {

  8     1,0,0,0,0,0,

  9     1,1,0,0,0,0,

 10     1,1,1,0,0,0,

 11     1,1,1,1,0,0,

 12     1,1,1,1,1,0,

 13     1,1,1,1,1,1,//5

 14     1,0,0,0,0,1,

 15     1,1,0,0,0,1,

 16     1,1,1,0,0,1,

 17     1,1,1,1,0,1

 18 };//光标移动域

 19 int way[N][8],top;//排列与状态、步数

 20 struct Data

 21 {

 22     int ar[6],step,state,pos;//数列,步数,光标状态

 23 };

 24 bool mark[6][6][6][6][6][6][6][10];//bfs状态集

 25 void bfs()

 26 {

 27     Data a,b,stk[N];

 28     int f,r;

 29     f=r=top=0;

 30     for(int i=0;i<6;i++)

 31         a.ar[i]=i;

 32     a.step=a.state=a.pos=0;

 33     stk[r++]=a;

 34     memset(mark,false,sizeof(mark));

 35     mark[a.ar[0]][a.ar[1]][a.ar[2]][a.ar[3]][a.ar[4]][a.ar[5]][a.pos][a.state]=true;

 36     while(f!=r)

 37     {

 38         a=stk[f++];

 39         if(f==N)

 40             f=0;

 41         for(int i=0;i<6;i++)

 42             way[top][i]=a.ar[i];

 43         way[top][6]=a.state;

 44         way[top++][7]=a.step;

 45         b=a;

 46         b.step++;

 47         if(b.pos>0)

 48         {

 49             swap(b.ar[0],b.ar[b.pos]);

 50             if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state])

 51             {

 52                 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true;

 53                 stk[r++]=b;

 54                 if(r==N)

 55                     r=0;

 56             }

 57             swap(b.ar[0],b.ar[b.pos]);

 58         }

 59         if(b.pos<5)

 60         {

 61             int temp=b.state;

 62             b.pos++;

 63             if(b.pos>b.state||(b.state>5&&b.pos>b.state-6))

 64             {

 65                 if(b.state == 9) b.state = 5;

 66                 else ++b.state;

 67             }

 68             if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state])

 69             {

 70                 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true;

 71                 stk[r++]=b;

 72                 if(r==N)

 73                     r=0;

 74             }

 75             --b.pos;

 76             b.state=temp;

 77             swap(b.ar[5],b.ar[b.pos]);

 78             if(b.state<5)

 79                 b.state+=6;

 80             if(!mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state])

 81             {

 82                 mark[b.ar[0]][b.ar[1]][b.ar[2]][b.ar[3]][b.ar[4]][b.ar[5]][b.pos][b.state]=true;

 83                 stk[r++]=b;

 84                 if(r==N)

 85                     r=0;

 86             }

 87         }

 88     }

 89 }

 90 int main()

 91 {

 92     bfs();

 93     int start,end;

 94     while(scanf("%d%d",&start,&end)!=EOF)

 95     {

 96         int a[6],b[6];

 97         for(int i=5;i>=0;i--)

 98         {

 99             a[i]=start%10;

100             b[i]=end%10;

101             start/=10;

102             end/=10;

103         }

104         int ans=1<<29,st;

105         for(int i=0,j;i<top;i++)

106         {

107             st=way[i][7];

108             for(j=0;j<6;j++)

109             {

110                 if(a[way[i][j]]!=b[j]&&!sign[way[i][6]][j])

111                     break;

112                 else

113                     st+=abs(a[way[i][j]]-b[j]);

114             }

115             if(j==6&&st<ans)

116                 ans=st;

117         }

118         printf("%d\n",ans);

119     }

120     return 0;

121 }

你可能感兴趣的:(poj)