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


     阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为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;
    }


    ——by zhber,转载请注明来源
  • 相关阅读:
    Preparing for Merge Sort(二分)
    Polycarp's phone book(unordered_mpa 大法好)
    Yet Another Task with Queens
    nginx 初时
    JSON.stringfiy 序列化
    css grid布局使用
    遍历对象属性5种方法,排列顺序规则
    归并方法
    处理地图经纬度,保留6位小数
    js 操作方法
  • 原文地址:https://www.cnblogs.com/zhber/p/4036066.html
Copyright © 2020-2023  润新知