problem 2416

考虑用广度优先搜索。

广度优先主要需要解决的问题是如何存储状态,如何判断当前状态是否在以前出现过。

每个状态由四个数字组成,从1111 -- 9999 用一个四个下标(四维)的数组(s[9][9][9][9])存储,对应的值表示状态是否出现过,这样一来判重就变的十分简单。

还需要一个队列(数组q[9*9*9*9])来记录需要扩展的状态,pf与pe为队头和队尾。

每次扩展共有7(4+4+3)种情况,将其一一列出即可。

#include<stdlib.h>
 #include<stdio.h>
 #include<string.h>

#define
swap(a,b) {a=a^b;b=b^a;a=a^b;}
char s[9][9][9][9 ];
int q[9*9*9*9
],pe,pf;
int
 steps;
int
 from,to;
void copy(char from[4],char to[4
])
{
    
int i
;
    
for(i = 0; i < 4; i++
)
        to[i] 
=
 from[i];
}

void  bfs()
{
    
int i,k,flag = 0
;
    
char a[4],b[4
];
    k 
=
 from;
    q[pe
++=
 k;
    
while(1
)
    
{
        k 
= q[pf++
];
        
for(i = 0; i < 4; i++
)
        
{
            a[i] 
= k % 10
;
            k  
/ = 10
;
        }

        
for(i = 0; i < 3; i++)
        
{
            copy(a,b);
            
if(b[i] == b[i + 1
])
                
continue
;
            swap(b[i],b[i
+ 1
]);
                        k 
= b[0+ 10 * b[1+ 100 * b[2+ 1000 * b[3
];
            
if(k ==
 to)
                
return
;
            
if(s[b[0- 1][b[1- 1][b[2- 1][b[3- 1== 0
)
            
{
                q[pe
++=
 k;
                s[b[
0- 1][b[1- 1][b[2- 1][b[3- 1= 1
;
            }

        }

        
for(i = 0;  i < 4;  i++)
        
{
            copy(a,b);
            
if(b[i] < 9
)
                b[i]
++
;
            
else

                b[i] 
= 1;
                        k 
= b[0+ 10 * b[1+ 100 * b[2+ 1000 * b[3
];
            
if(k ==
 to)
                
return
;
            
if(s[b[0- 1][b[1- 1][b[2- 1][b[3- 1== 0
)
            
{
                q[pe
++=
 k;
                s[b[
0- 1][b[1- 1][b[2- 1][b[3- 1= 1
;
            }


            copy(a,b);
            
if(b[i] > 1)
                b[i]
--
;
            
else

                b[i] 
= 9;
                        k 
= b[0+ 10 * b[1+ 100 * b[2+ 1000 * b[3
];
            
if(k ==
 to)
                
return
;
            
if(s[b[0- 1][b[1- 1][b[2- 1][b[3- 1== 0
)
            
{
                q[pe
++=
 k;
                s[b[
0- 1][b[1- 1][b[2- 1][b[3- 1= 1
;
            }

        }

        
if(pf >= flag)
        
{
            flag 
=
 pe;
            steps
++
;
        }

    }

}

void  solve()
{
    scanf(
"%d",&
from);
    scanf(
"%d",&
to);
        
if(from ==
to)
        
{
                printf(
"0 "
);
                
return
;
        }

    pe 
= pf = 0;
    steps 
= 0
;
    memset(s,
0,sizeof(char)*9*9*9*9
);
    memset(q,
0,sizeof(int)*9*9*9*9
);
    bfs();
    printf(
"%d ",++
steps);
}

void  main()
{
    
int
 t;
#ifndef ONLINE_JUDGE
    freopen(
"test.txt","r"
,stdin);
#endif

    
while(scanf("%d",&t)!=EOF)
        
while(t--
)
            solve();
#ifndef ONLINE_JUDGE
    fclose(stdin);
#endif

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值