NKOJ P3631 密码锁

题目传送门

密码锁

时间限制 : 10000 MS

空间限制 : 65536 KB


 问题描述

何老板的密码锁由四位数字组成,每个数字的范围在1到9之间。
现在何老板告诉你开锁的密码,问,你最少需要多少步才能打开锁。

每一步,你可以进行下列三种操作:
1.向上转动密码盘,使一个数字加1(数字9再加1会变为1);
2.向下转动密码盘,使一个数字减1(数字1再减1会变为9);
3.交换两个相邻的数字(交换相邻两个密码盘,比如数字1357,交换左起第一和第二个密码盘后,得到3157)

输入格式

第一行,4个数字,表示锁当前的状态
第二行,4个数字,表示开锁的密码 

输出格式 

一个整数,表示打开锁需要的最少步数 

样例输入 

1 2 3 4
2 1 4 4 

样例输出 


 思路:

这道题典型的BFS模板

没啥说的,上代码!

void bfs()
{
	node now = first;
	now.num_of_step = 0;
	vis[now.a[0]][now.a[1]][now.a[2]][now.a[3]] = true;
	q.push(now);
	node next;
	while(!q.empty())
	{
		now = q.front();
		q.pop();
		if(now.a[0]==last.a[0]&&now.a[1]==last.a[1]
		        &&now.a[2]==last.a[2]&&now.a[3]==last.a[3])
		{
			printf("%d",now.num_of_step);
			return;
		}
		else
		{
			for(int i=0; i<4; i++)
			{
				next = now;
				next.a[i] ++;
				if(next.a[i] == 10)
					next.a[i] = 1;
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step ++;
					q.push(next);
				}
			}
			for(int i=0; i<4; i++)
			{
				next = now;
				next.a[i] --;
				if(next.a[i] == 0)
					next.a[i] = 9;
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step ++;
					q.push(next);
				}
			}
			for(int i = 0; i < 3; i++)
			{
				next = now;
				swap(next.a[i],next.a[i+1]);
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step++;
					q.push(next);
				}
			}
		}
	}
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans;
struct node
{
	int a[4];
	int num_of_step;
};
queue<node> q;
node first,last;
bool vis[11][11][11][11];
void in_it()
{
	for(int i=0; i<4; i++)
		scanf("%d",&first.a[i]);
	for(int i=0; i<4; i++)
		scanf("%d",&last.a[i]);
}
void find()
{
	node now = first;
	now.num_of_step = 0;
	vis[now.a[0]][now.a[1]][now.a[2]][now.a[3]] = true;
	q.push(now);
	node next;
	while(!q.empty())
	{
		now = q.front();
		q.pop();
		if(now.a[0]==last.a[0]&&now.a[1]==last.a[1]
		        &&now.a[2]==last.a[2]&&now.a[3]==last.a[3])
		{
			printf("%d",now.num_of_step);
			return;
		}
		else
		{
			for(int i=0; i<4; i++)
			{
				next = now;
				next.a[i] ++;
				if(next.a[i] == 10)
					next.a[i] = 1;
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step ++;
					q.push(next);
				}
			}
			for(int i=0; i<4; i++)
			{
				next = now;
				next.a[i] --;
				if(next.a[i] == 0)
					next.a[i] = 9;
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step ++;
					q.push(next);
				}
			}
			for(int i = 0; i < 3; i++)
			{
				next = now;
				swap(next.a[i],next.a[i+1]);
				if(!vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]])
				{
					vis[next.a[0]][next.a[1]][next.a[2]][next.a[3]] = true;
					next.num_of_step++;
					q.push(next);
				}
			}
		}
	}
}
int main()
{
	in_it();
	find();
	return 0;
}

AC记录


The end

最后:制作不易,点个赞吧,求求了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值