题意:就是给你n组的四位数,在一次变化中又一位数字可以变化,而变化的方式为加一减一或者是与隔壁的互换,注意,是每一个数字都可以,
求最少的变化次数到达目标的数字
一看这个就应该知道这是一个bfs的题目,广搜么,不过要注意的就是标记,不然很有可能也出不来
我的代码写的比较繁琐,也比较糙,这个写的太复杂了,不过你也可以用循环来代替我的大部分代码,可以减少很多的书写量
#include <stdio.h> #include <iostream> #include <string.h> #include <queue> using namespace std; int ans; queue<int >s; bool mark[10005]; int step[10005]; int bfs(int x) { int he,y,c[4];while(!s.empty()) s.pop(); if(x==ans) return 0; s.push(x); mark[x]=false; while(!s.empty()) { he=s.front(); s.pop(); c[0]=he/1000; //这个的目的就是判断每一位数字是否为9或者1,因为9加1就是1了,而1减1也会变成9, c[1]=(he-c[0]*1000)/100; c[2]=(he-c[0]*1000-c[1]*100)/10; c[3]=he%10; if(c[0]==9&&mark[he-8000]){s.push(he-8000);mark[he-8000]=false;step[he-8000]=step[he]+1;if(he-8000==ans){printf("%d\n",step[he-8000]);return 0;}} else if(mark[he+1000]&&c[0]!=9){s.push(he+1000);mark[he+1000]=false;step[he+1000]=step[he]+1;if(he+1000==ans){printf("%d\n",step[he+1000]);return 0;}} //切记这里要加一个那位数不能为9或者1,否则可能出现3位数的情况 if(c[1]==9&&mark[he-800]){s.push(he-800);mark[he-800]=false;step[he-800]=step[he]+1;if(he-800==ans){printf("%d\n",step[he-800]);return 0;}} else if(mark[he+100]&&c[1]!=9){s.push(he+100);mark[he+100]=false;step[he+100]=step[he]+1;if(he+100==ans){printf("%d\n",step[he+100]);return 0;}} if(c[2]==9&&mark[he-80]){s.push(he-80);mark[he-80]=false;step[he-80]=step[he]+1;if(he-80==ans){printf("%d\n",step[he-80]);return 0;}} else if(mark[he+10]&&c[2]!=9){s.push(he+10);mark[he+10]=false;step[he+10]=step[he]+1;if(he+10==ans){printf("%d\n",step[he+10]);return 0;}} if(c[3]==9&&mark[he-8]){s.push(he-8);mark[he-8]=false;step[he-8]=step[he]+1;if(he-8==ans){printf("%d\n",step[he-8]);return 0;}} else if(mark[he+1]&&c[3]!=9){s.push(he+1);mark[he+1]=false;step[he+1]=step[he]+1;if(he+1==ans){printf("%d\n",step[he+1]);return 0;}} if(c[0]==1&&mark[he+8000]){s.push(he+8000);mark[he+8000]=false;step[he+8000]=step[he]+1;if(he+8000==ans){printf("%d\n",step[he+8000]);return 0;}} else if(mark[he-1000]&&c[0]!=1){s.push(he-1000);mark[he-1000]=false;step[he-1000]=step[he]+1;if(he-1000==ans){printf("%d\n",step[he-1000]);return 0;}} if(c[1]==1&&mark[he+800]){s.push(he+800);mark[he+800]=false;step[he+800]=step[he]+1;if(he+800==ans){printf("%d\n",step[he+800]);return 0;}} else if(mark[he-100]&&c[1]!=1){s.push(he-100);mark[he-100]=false;step[he-100]=step[he]+1;if(he-100==ans){printf("%d\n",step[he-100]);return 0;}} if(c[2]==1&&mark[he+80]){s.push(he+80);mark[he+80]=false;step[he+80]=step[he]+1;if(he+80==ans){printf("%d\n",step[he+80]);return 0;}} else if(mark[he-10]&&c[2]!=1){s.push(he-10);mark[he-10]=false;step[he-10]=step[he]+1;if(he-10==ans){printf("%d\n",step[he-10]);return 0;}} if(c[3]==1&&mark[he+8]){s.push(he+8);mark[he+8]=false;step[he+8]=step[he]+1;if(he+8==ans){printf("%d\n",step[he+8]);return 0;}} else if(mark[he-1]&&c[3]!=1){s.push(he-1);mark[he-1]=false;step[he-1]=step[he]+1;if(he-1==ans){printf("%d\n",step[he-1]);return 0;}} y=c[1]*1000+c[0]*100+c[2]*10+c[3]; //这个就是与隔壁的交换,只有三种情况,就是每一个都与右边的交换。 if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}} y=c[0]*1000+c[2]*100+c[1]*10+c[3]; if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}} y=c[0]*1000+c[1]*100+c[3]*10+c[2]; if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}} if(he==ans) { printf("%d\n",step[he]); return 0; } } return 0; } int main() { int n,start; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&start,&ans); memset(mark,true,sizeof(mark)); memset(step,0,sizeof(step)); step[start]=0; bfs(start); } return 0; }