->题目请戳这里<-
题目大意:给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