现在的位置: 首页 > 综合 > 正文

2014.7.8模拟赛【聪明的打字员】

2018年01月13日 ⁄ 综合 ⁄ 共 2923字 ⁄ 字号 评论关闭

 阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好。

 不幸的是,出于保密的需要,该部门用于输入密码的键盘是特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0,Swap1,Up,Down,Left,Right。为了说明这6个键的

用,我们先定义录入区的6个位置的编号,从左至右依次为l,2,3,4,5,6。下面列出每个键的作用:

Swap0:按Swap0,光标位置不变,将光标所在位置的数字与录入区的1号位置的数字(左起第一个数字)交换。如果光标已经处在录入区的1号位置,则按Swap0键之后,录入区的数字不变;

Swap1:按Swap1,光标位置不变,将光标所在位置的数字与录入区的6号位置的数字(左起第六个数字)交换。如果光标已经处在录入区的6号位置,则按Swap1键之后,录入区的数字不变;

    Up:按up,光标位置不变,将光标所在位置的数字加1(除非该数字是9)。例如,如果  光标所在位置的数字为2,按up之后,该处的数字变为3;如果该处数字为9,则按up之后,数字不变,光标位置也不变;

    Down:按Down,光标位置不变,将光标所在位置的数字减1(除非该数字是0)。如果该 处数字为0,则按Down之后,数字不变,光标位置也不变;

    Left:按Left,光标左移一个位置,如果光标已经在录入区的1号位置(左起第一个位  置)上,则光标不动;

    Right:按Right,光标右移一个位置,如果光标已经在录入区的6号位置(左起第六个  位置)上,则光标不动。当然,为了使这样的键盘发挥作用,每次录入密码之前,录入区总会随机出现一个长度为6的初始密码,而且光标固定出现在1号位置上。当巧妙地使用上述六个特殊键之后,可以得到目标密码,这时光标允许停在任何一个位置。

    现在,阿兰需要你的帮助,编写一个程序,求出录入一个密码需要的最少的击键次数。

【输入格式】

    仅一行,含有两个长度为6的数,前者为初始密码,后者为目标密码,两个密码之间用  一个空格隔开。

【输出格式】

    仅一行,含有一个正整数,为最少需要能击键次数。

【样例输入】

    123456 654321

【样例输出】

    11

题意是给定两个长度为6的串,要求用最小的步数从1串变成2串

ps:火男学长太神了,看一眼题目不屑的说,隐式图搜索。

唉真的是搜索,让我调了1个多小时

首先肯定用双向广搜啦

状态有600w。因为是6个光标的位置 * 100w的数据的状态

具体实现最好直接用数字保存状态,否则像hzwer那样字符串乱搞就T了,不要学他

另外,我写的很丑,勿喷

#include<cstdio>
const int mul[8]={0,1,10,100,1000,10000,100000,1000000};
int q[7000010];
int step[7000010];
int mark[7000010];
int a,b,t=0,w=7,now,opr,mov,side;
inline int abs(int x)
{if(x<0)x=-x;return x;}
int main()
{
	freopen("typer.in","r",stdin);
	freopen("typer.out","w",stdout);
	scanf("%d%d",&a,&b);
	q[1]=6*mul[7]+a;
	mark[q[1]]=1;
	for (int i=2;i<=7;i++)
	{
	  q[i]=b+(i-1)*mul[7];
	  if (mark[q[i]])
		{
			printf("0");
			return 0;
		}
	  mark[q[i]]=-i;
	}
	while (t<w)
	{
		now=q[++t];
		mov=step[t];
		opr=now/mul[7];
		side=0;
		if (mark[now]<0) side=-1;
		if (mark[now]>0) side=1;
		
		
		if ((now/mul[opr])%10) //down
		{
			if (side*mark[now-mul[opr]]<0)
			{
				printf("%d",mov+1+step[abs(mark[now-mul[opr]])]);
				return 0;
			}
			if (!mark[now-mul[opr]])
			{
			q[++w]=now-mul[opr];
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
		
		
		if ((now/mul[opr])%10!=9) //up
		{
			if (side*mark[now+mul[opr]]<0)
			{
				printf("%d",mov+1+step[abs(mark[now+mul[opr]])]);
				return 0;
			}
			if (!mark[now+mul[opr]])
			{
			q[++w]=now+mul[opr];
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
		
		
		if (opr!=1) //swap1
		{
			
			int s=(now/mul[opr])%10,t=now%10;
			if (side*mark[now+(t-s)*mul[opr]+(s-t)]<0)
			{
				printf("%d",mov+1+step[abs(mark[now+(t-s)*mul[opr]+(s-t)])]);
				return 0;
			}
			if (!mark[now+(t-s)*mul[opr]+(s-t)])
			{
			q[++w]=now+(t-s)*mul[opr]+(s-t);
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
		
		
		if (opr!=6) //swap0
		{
			int s=(now/mul[opr])%10,t=(now/mul[6])%10;
			if (side*mark[now+(t-s)*mul[opr]+(s-t)*mul[6]]<0)
			{
				printf("%d",mov+1+step[abs(mark[now+(t-s)*mul[opr]+(s-t)*mul[6]])]);
				return 0;
			}
			if (!mark[now+(t-s)*mul[opr]+(s-t)*mul[6]])
			{
			q[++w]=now+(t-s)*mul[opr]+(s-t)*mul[6];
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
		
		
		if (opr!=1) //left
		{
			if (side*mark[now-mul[7]]<0)
			{
				printf("%d",mov+1+step[abs(mark[now-mul[7]])]);
				return 0;
			}
			if (!mark[now-mul[7]])
			{
			q[++w]=now-mul[7];
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
		
		
		if (opr!=6) //right
		{
			if (side*mark[now+mul[7]]<0)
			{
				printf("%d",mov+1+step[abs(mark[now+mul[7]])]);
				return 0;
			}
			if (!mark[now+mul[7]])
			{
			q[++w]=now+mul[7];
			step[w]=mov+1;
			mark[q[w]]=w*side;
			}
		}
	}
	return 0;
}

抱歉!评论已关闭.