这道题是自己第二次打, 第一次的用的是count标记次数,那个是模仿大神写的所以有点不懂, 今天自己又用结构体打了一遍,虽然很艰难,但是收获确实很多的啊,这道题的基本题意就是让你由一个说变成下个数需要几步,每次只能改变数的一位,而且改变完的数必须是素数,所以首先要打素数表,然后一个一个列举出来所有的情况就行了,这道题的要求是找最短的方法,但是如果用队列来解这题的话就不用考虑了。因为用队列求出来的都是最短的。这道题我遇到的问题就是千位必须大于0要不然第二个测试数据的结果就变成5了所有我最后加了一个条件然后AC了。。。且行且珍惜---
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<iostream>
#include
<algorithm>
#include
<queue>
using
namespace
std
;
int
prime
[
10000
]; //标记素数,非素数为1;
int
v
[
10000
]; //标记这个数在之前是否压入队列里
int
ans
,
state
; //最后的步数和是否能找到那个数
int
t
[
4
]; //储存 千 百 十 个
struct
node
{
int
n
;
int
step
;
}
;
void
Prime
() //打素数表
{
int
i
,
j
;
memset
(
prime
,
0
,
sizeof
(
prime
));
for
(
i
=
2
;
i
<
10000
;
i
++)
{
if
(!
prime
[
i
])
{
for
(
j
=
i
+
i
;
j
<
10000
;
j
+=
i
)
prime
[
j
]=
1
;
}
}
}
void
bfs
(
int
a
,
int
b
)
{
queue
<
node
>
q
;
struct
node
x
;
int
i
,
j
;
x
.
n
=
a
;
x
.
step
=
0
;
q
.
push
(
x
);
if
(
x
.
n
==
b
)
{
state
=
1
;
ans
=
x
.
step
;
return
;
}
memset
(
v
,
0
,
sizeof
(
v
));
while
(!
q
.
empty
())
{
x
=
q
.
front
();
q
.
pop
();
if
(
x
.
n
==
b
)
{
ans
=
x
.
step
;
break
;
}
v
[
x
.
n
]=
1
;
t
[
0
]=
x
.
n
/
1000
;
t
[
1
]=
x
.
n
/
100
%
10
;
t
[
2
]=
x
.
n
%
100
/
10
;
t
[
3
]=
x
.
n
%
10
;
for
(
i
=
0
;
i
<
4
;
i
++)
{
int
m
=
t
[
i
],
sum
; ///一定把m存下来要不然就然后再j循环完后就达不到只改变一位的效果了
for
(
j
=
0
;
j
<
10
;
j
++)
{
t
[
i
]=
j
;
sum
=
t
[
0
]*
1000
+
t
[
1
]*
100
+
t
[
2
]*
10
+
t
[
3
];
if
(
t
[
0
]==
0
)
continue
;
if
(!
v
[
sum
]
&&
!
prime
[
sum
])
{
struct
node
e
;
e
.
n
=
sum
;
e
.
step
=
x
.
step
+1
;
if
(
e
.
n
==
b
)
{
state
=
1
;
ans
=
e
.
step
;
break
;
}
q
.
push
(
e
);
v
[
sum
]=
1
;
}
}
t
[
i
]=
m
;
if
(
state
)
break
;
}
if
(
state
)
break
;
}
}
int
main
()
{
int
t
;
scanf
(
"%d"
,&
t
);
Prime
();
prime
[
0
]=
1
;
prime
[
1
]=
1
;
while
(
t
--)
{
int
a
,
b
;
scanf
(
"%d%d"
,&
a
,&
b
);
ans
=-
1
;
state
=
0
;
bfs
(
a
,
b
);
if
(
ans
==-
1
&&
!
state
)
printf
(
"Impossible
\n
"
);
else
printf
(
"%d
\n
"
,
ans
);
}
}