题目大意:给2个长度为4的数字串,求从第一个串变到第二个串最少要几步。
每一步变换情况有:
1:每个数字+1,9+1 = 1;
2:每个数字-1,1-1 = 9;
3:某个数字和与其相邻的数字交换,第一个和最后一个数字不算相邻。
题目分析:bfs~,这题单向bfs也可以过,不过想练习一下双向bfs,话说还是第一次写双向bfs。所以先找道简单的切。队列决定自己写,省时间,用循环队列节省空间。不过跑出来好像也不是很快,进不了0ms,好吧,我又写挫了。。。
单向bfs:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
char s1[5],s2[5];
bool mark[10][10][10][10];
struct node{
char s[5];
int count;
}t,now,last;
void Bfs()
{
queue<node>q;
memset(mark,0,sizeof(mark));
strcpy(t.s,s1);
t.count = 0;
mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
q.push(t);
while(!q.empty())
{
now = q.front();
q.pop();
if(strcmp(s2,now.s) == 0)
{
printf("%d\n",now.count);
return;
}
char c;
for(int i = 0;i < 4;i ++)
{
if(i < 3)//该数字与右边的换
{
strcpy(t.s,now.s);
c = t.s[i];
t.s[i] = t.s[i+1];
t.s[i+1] = c;
if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
{
t.count = now.count + 1;
mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
if(strcmp(s2,t.s) == 0)
{
printf("%d\n",t.count);
return;
}
q.push(t);
}
}
strcpy(t.s,now.s);
t.s[i] = now.s[i] + 1;//加法
if(t.s[i] - '0' > 9)
t.s[i] = '1';
if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
{
t.count = now.count + 1;
mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
if(strcmp(s2,t.s) == 0)
{
printf("%d\n",t.count);
return;
}
q.push(t);
}
strcpy(t.s,now.s);
t.s[i] = now.s[i] - 1;//减法
if(t.s[i] - '0' == 0)
t.s[i] = '9';
if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
{
t.count = now.count + 1;
mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
if(strcmp(s2,t.s) == 0)
{
printf("%d\n",t.count);
return;
}
q.push(t);
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t --)
{
scanf("%s%s",s1,s2);
Bfs();
}
return 0;
}//31MS 344K
双向bfs:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
using namespace std;
int flag[2][10][10][10][10];
char s1[10],s2[10];
char ss[10],now[10];
struct que
{
char s[100005][10];
int head,tail,size;
void init()
{
head = tail = 0;
size = 100005;
}
bool empty()
{
return head == tail;
}
char * top()
{
return s[head];
}
void pop()
{
head ++;
head %= size;
}
void push(char a[])
{
strcpy(s[tail],a);
tail ++;
tail %= size;
}
}q[2];
int Bfs()
{
int i,j;
q[0].init();
q[1].init();
int step = 0;
memset(flag,-1,sizeof(flag));
if(strcmp(s1,s2) == 0)
return 0;
q[0].push(s1);//正向搜
q[1].push(s2);//反向搜
flag[0][s1[0] - '0'][s1[1] - '0'][s1[2] - '0'][s1[3] - '0'] = 0;
flag[1][s2[0] - '0'][s2[1] - '0'][s2[2] - '0'][s2[3] - '0'] = 0;
while(!q[0].empty() && !q[1].empty())
{
for(i = 0;i <= 1;i ++)
{
strcpy(now,q[i].top());
q[i].pop();
step = flag[i][now[0] - '0'][now[1] - '0'][now[2] - '0'][now[3] - '0'];
for(j = 0;j < 4;j ++)
{
if(j < 3)//与右边交换
{
strcpy(ss,now);
char c = ss[j];
ss[j] = ss[j + 1];
ss[j + 1] = c;
if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
{
flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
{
return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
}
q[i].push(ss);
}
}
strcpy(ss,now);
if(ss[j] == '9')
ss[j] = '1';
else
ss[j] ++;
if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
{
flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
{
return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
}
q[i].push(ss);
}
strcpy(ss,now);
if(ss[j] == '1')
ss[j] == '9';
else
ss[j] --;
if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
{
flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
{
return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
}
q[i].push(ss);
}
}
if(!q[i].empty())//要把同一层的搜完。。。
{
strcpy(now,q[i].top());
if(flag[i][now[0] - '0'][now[1] - '0'][now[2] - '0'][now[3] - '0'] == step)
i --;
}
}
}
}
void input()
{
char c;
while(isspace(c = getchar()))
;
s1[0] = c;
s1[1] = getchar();
s1[2] = getchar();
s1[3] = getchar();
while(isspace(c = getchar()))
;
s2[0] = c;
s2[1] = getchar();
s2[2] = getchar();
s2[3] = getchar();
}
int main()
{
int t;
scanf("%d",&t);
while(t --)
{
//scanf("%s%s",s1,s2);
input();//还是很慢。。。
printf("%d\n",Bfs());
}
return 0;
}
//15MS 440K