BFS+剪枝--hdoj1195(不错)

来源:互联网 发布:南通seo招聘 编辑:程序博客网 时间:2024/06/05 15:08

感觉这道题还不错,可能是因为自己做的不好的原因。

题意:给你两个密码,一个袁辉密码,一个正确密码,问最少经过几步可以变为正确密码,每次可以+1,-1,或者相邻的交换。

思路:只要每次把变化的数压入队列中就行。但要注意剪枝,刚开始,忘了对每个出现过的数做标记,导致内存超限,做的也很麻烦,搞得自己很被动;刚开始还犯了个很大的错误,就是对每位上的数连续加完之后,在处理下一位,这样是大错特错,因为求的是最少的步骤,以后在这种题上要注意!

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;struct node{   int num[4],step;};node first,last;bool visit[10][10][10][10],flag;void bfs(){   int i;   node p,q;   queue<node> Q;   memset(visit,false,sizeof(visit));   flag=true;   first.step=0;   p=first;   visit[p.num[0]][p.num[1]][p.num[2]][p.num[3]]=true;   Q.push(p);   while(!Q.empty())   {      p=Q.front();Q.pop();  flag=true;  for(i=0;i<4;i++)  if(p.num[i]!=last.num[i])  {      flag=false;  break;  };  if(flag)  {     printf("%d\n",p.step); return;  }    for(i=0;i<4;i++)//+1  {  q=p;     if(p.num[i]==9) q.num[i]=1; else q.num[i]=p.num[i]+1; q.step=p.step+1; if(!visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]) {    visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]=true;Q.push(q); }  }  for(i=0;i<4;i++)//-1  {  q=p;     if(p.num[i]==1) q.num[i]=9; else q.num[i]=p.num[i]-1; q.step=p.step+1; if(!visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]) {    visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]=true;Q.push(q); }  }  for(i=0;i<3;i++)//相邻交换  {     q=p; q.num[i]=p.num[i+1]; q.num[i+1]=p.num[i]; q.step=p.step+1; if(!visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]) {    visit[q.num[0]][q.num[1]][q.num[2]][q.num[3]]=true;Q.push(q); }  }   }}int main(){   int cas,i;   char chf[5],chl[5];   scanf("%d",&cas);   while(cas--)   {      scanf("%s%s",chf,chl);  for(i=0;i<4;i++)  {     first.num[i]=chf[i]-'0'; last.num[i]=chl[i]-'0';  }  bfs();   }   return 0;}


 

原创粉丝点击