HDU 1195 Open the Lock

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1195


思路1:单项BFS


三个方向:加1,减1,相邻交换,其中9+1=1,1-1=9,最左边不与最右边相邻


#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;
}


思路2:双向BFS


分别从两头一层一层搜索,相遇时输出答案并跳出搜索


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
	int a[4],step;
};
int v1[10][10][10][10],v2[10][10][10][10];
node ft,lt;
void bbfs()
{
	int i,k,temp1,temp2;
	node  qf, ql, pf, pl;
	queue<node>  Q1,  Q2;
	ft.step=0; pf=ft;
	lt.step=0; pl=lt;
	memset(v1,-1,sizeof(v1));
	memset(v2,-1,sizeof(v2));
	v1[pf.a[0]][pf.a[1]][pf.a[2]][pf.a[3]]=0;
	v2[pl.a[0]][pl.a[1]][pl.a[2]][pl.a[3]]=0;
	Q1.push(pf), Q2.push(pl);
	temp1=temp2=0;
	while(1)
	{
		while(!Q1.empty()&&Q1.front().step==temp1)//正搜
		{
			pf=Q1.front(); Q1.pop();
			if((k=v2[pf.a[0]][pf.a[1]][pf.a[2]][pf.a[3]])!=-1)//判断是否反搜过
			{
				printf("%d\n",pf.step+k);
				return;
			}
			for(i=0;i<4;i++)//+1;
			{
				qf=pf;
				if(pf.a[i]==9) qf.a[i]=1;
				else qf.a[i]=pf.a[i]+1;
				qf.step=pf.step+1;
				if((k=v2[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]])!=-1)//判断是否反搜过
				{
				    printf("%d\n",qf.step+k);
					return;
				}
				if(v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]==-1)
				{
					v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]=qf.step;
					Q1.push(qf);
				}
			}
			for(i=0;i<4;i++)//-1;
			{
				qf=pf;
				if(pf.a[i]==1) qf.a[i]=9;
				else qf.a[i]=pf.a[i]-1;
				qf.step=pf.step+1;
				if((k=v2[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]])!=-1)
				{
				    printf("%d\n",qf.step+k);
					return;
				}
				if(v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]==-1)
				{
					v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]=qf.step;
					Q1.push(qf);
				}
			}
			for(i=0;i<3;i++)
			{
				qf=pf;
				qf.a[i]=pf.a[i+1];
				qf.a[i+1]=pf.a[i];
				qf.step=pf.step+1;
				if((k=v2[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]])!=-1)
				{
				    printf("%d\n",qf.step+k);
					return;
				}
				if(v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]==-1)
				{
					v1[qf.a[0]][qf.a[1]][qf.a[2]][qf.a[3]]=qf.step;
					Q1.push(qf);
				}
			}	
		}
        temp1=Q1.front().step;

		while(!Q2.empty()&&Q2.front().step==temp2)//反搜;
		{
			pl=Q2.front();Q2.pop();
			if((k=v1[pl.a[0]][pl.a[1]][pl.a[2]][pl.a[3]])!=-1)
			{
				printf("%d\n",pl.step+k);
				return;
			}
			for(i=0;i<4;i++)//+1;
			{
				ql=pl;
				if(pl.a[i]==9) ql.a[i]=1;
				else ql.a[i]=pl.a[i]+1;
				ql.step=pl.step+1;
				if((k=v1[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]])!=-1)
				{
				    printf("%d\n",ql.step+k);
					return;
				}
				if(v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]==-1)
				{
					v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]=ql.step;
					Q2.push(ql);
				}
			}
			for(i=0;i<4;i++)//-1;
			{
				ql=pl;
				if(pl.a[i]==1) ql.a[i]=9;
				else ql.a[i]=pl.a[i]-1;
				ql.step=pl.step+1;
				if((k=v1[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]])!=-1)
				{
				    printf("%d\n",ql.step+k);
					return;
				}
				if(v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]==-1)
				{
					v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]=ql.step;
					Q2.push(ql);
				}
			}
			for(i=0;i<3;i++)//相邻交换
			{
				ql=pl;
				ql.a[i]=pl.a[i+1];
				ql.a[i+1]=pl.a[i];
				ql.step=pl.step+1;
				if((k=v1[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]])!=-1)
				{
				    printf("%d\n",ql.step+k);
					return;
				}
				if(v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]==-1)
				{
					v2[ql.a[0]][ql.a[1]][ql.a[2]][ql.a[3]]=ql.step;
					Q2.push(ql);
				}
			}
		}
		temp2=Q2.front().step;
	}	
}
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++)
		{
			ft.a[i]=chf[i]-'0';
			lt.a[i]=chl[i]-'0';
		}
		bbfs();
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值