hiho 1426

题目大意:

问最少通过多少次操作能将字符串"12345"变成一个长度为5并且只由'0'~'9'字符组成的字符串

每次操作有3种选择

1.交换相邻的两个数字

2.将一个数字加1,如果大于9就模10

3.将一个数字乘2,如果大于9就模10

2操作最多能用3次,3操作最多能用2次。

思路:题目中可能有100000组测试数据,所以可以用bfs来预处理,得出“12345”通过以上操作能转换成的字符串的最少操作次数。

易错点:因为第2步操作仅能使用3次,第3步操作仅能操作2次,所以必须开一个res[5][5][100005]的数组,res[i][j][k]表示意思第2步操作还可以进行i次,第3步操作还可以进行j次所得到数字为k的最少操作次数,将此状态入队列。刚开始仅仅开了一个res[i]表示状态,导致有些情况没有考虑,如前面已经进行了2次第3步操作得到一个数字k,这时候已经无法进行第3步操作,但是其实可能有其他操作可以使用比如1次第3步操作得到这个数字k,那么此时还可以继续进行第3步操作,有可能使操作步数减少。如果只开一维res数组则无法考虑这种情况。


代码如下:

#include
using namespace std;
#include
#include
#include
#include
#include
const int inf = 200000;
int res[5][5][100005];
int result[100005];
int min(int x,int y)
{
if(xreturn y;
}
struct num
{
int sec;
int third;
int val;
int pace;
};
void turn(int x,int a[])
{
int i;
for(i=4;i>=0;i--)
{
a[i] = x % 10;
x /= 10;
}
}
int change(int b[])
{
int i;
int x = 0;
for(i=0;i<5;i++) x = x * 10 + b[i];
return x;

queue que;
void bfs(int now)
{
num tm;
tm.val = now;
tm.sec = 3;
tm.third = 2;
tm.pace = 0;
que.push(tm);
int i,j;
while(!que.empty())
{
tm = que.front();
que.pop();
int a[5];
turn(tm.val,a);
for(i=1;i<5;i++)
{
swap(a[i-1],a[i]);
int x = change(a);
if(res[tm.sec][tm.third][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec;
tt.third = tm.third;
tt.val = x;
res[tm.sec][tm.third][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
swap(a[i-1],a[i]);
}
int b[5];
if(tm.sec>0)
{
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
b[j] = a[j];
}
b[i] = (a[i] + 1) % 10;
int x = change(b);
if(res[tm.sec-1][tm.third][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec - 1;
tt.third = tm.third;
tt.val = x;
res[tm.sec-1][tm.third][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
}
}
if(tm.third>0)
{
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
b[j] = a[j];
}
b[i] = (a[i] * 2) % 10;
int x = change(b);
if(res[tm.sec][tm.third-1][x]==inf)
{
num tt;
tt.pace = tm.pace + 1;
tt.sec = tm.sec;
tt.third = tm.third - 1;
tt.val = x;
res[tm.sec][tm.third-1][x] = tt.pace;
result[x] = min(result[x],tt.pace);
que.push(tt);
}
}
}
}
}
int main()
{
int now = 12345;
int m,i,j,k;
for(i=0;i<=3;i++)
for(j=0;j<=2;j++)
for(k=0;k<100000;k++) res[i][j][k] = inf;
fill(result,result+100003,inf);
res[3][2][now] = 0;
result[now] = 0;
bfs(now);
while(~scanf("%d",&m))
{
if(result[m]==inf) printf("-1\n");
else printf("%d\n",result[m]);
}
}

你可能感兴趣的:(搜索)