ZCMU—1160

1160: 松哥的计算机

Time Limit: 1 Sec  Memory Limit: 128 MB
[Submit][Status][Web Board]

Description

松哥有一台只有一个数据栈的计算机,支持整数的5种运算:ADD,SUB.MUL,DIV,DUP.假设栈顶的3个元素分别为a,b,c,则5种运算的效果依次如下: ADD,a和b依次出栈,把a+b压入栈.SUB, a和b依次出栈,把b-a压入栈.MUL, a和b依次出栈,把a*b压入栈.DIV, a和b依次出栈,把b/a压入栈.DUP, a出栈,再把两个a压入栈.遇到下列情况时,松哥的计算器会产生错误,所以不能执行该运算.执行DIV操作时栈顶元素为0,执行ADD,SUM,MUL,DIV操作时栈中只有一个元素.,初始栈中只有一个元素a,松哥想知道最少经过几次计算后,栈顶元素能变成b.

Input

多组测试数据。每组测试数据包含两个整数(|a|,|b|<=10)

Output

对于每组测试数据输出至少需要经过几次计算才能使栈顶元素变为b.若永远不能使栈顶元素变成b则输出-1.

Sample Input

1 2
1 3

Sample Output

2
4

HINT

对于第一组case,栈中初始元素为1.

经过一次DUP运算后变为1,1

再经过一次ADD运算后变为2

所以答案为2

【分析】

经典BFS,刘汝佳老师的算法竞赛入门里的例题....被坑了0,0这个点....然后因为数据可能过大,手动筛除一些不可能继续操作的状态,然后对于-1的情况,显然只有当a=0,b!=0的时候才可能是-1,否则的话不论a和b是多少,都一定可以做出答案的
【代码】
#include <stdio.h>
  
struct xx{  
    int pos;  
    int s[100];  
    int pre;  
    int op;  
}p[100000];  
int a,b;
void find()  
{  
    int head, end;  
    p[head = end = 0].pos = 1;  
    p[head].s[0] = a;  
    p[head].pre = -1;  
    p[end++].op = -1;  
    while (head < end)  
    {  
        xx w = p[head];
		if (w.pos>14) continue;
		if (w.s[w.pos-1] == b)  
        {  
  			int ans=0;
  			while (w.pre!=-1) ans++,w=p[w.pre];
  			printf("%d\n",ans); 
  			return;  
        }  
        if (w.pos > 1)  
        {  
            xx m = w;  
            int x1 = m.s[--m.pos];  
            int x2 = m.s[--m.pos];  
            m.s[m.pos++] = x1 + x2;  
            m.pre = head;  
            m.op = 0;  
            p[end++] = m;  
        }  
  
        if (w.pos > 1)  
        {  
            xx m = w;  
            int x1 = m.s[--m.pos];  
            int x2 = m.s[--m.pos];  
            m.s[m.pos++] = x2 - x1;  
            m.pre = head;  
            m.op = 1;  
            p[end++] = m;  
        }  
  
        if (w.pos > 1)  
        {  
            xx m = w;  
            int x1 = m.s[--m.pos];  
            int x2 = m.s[--m.pos];  
            m.s[m.pos++] = x1 * x2;  
            m.pre = head;  
            m.op = 2;  
            p[end++] = m;  
        }  
  
        if (w.pos > 1 && w.s[w.pos - 1])  
        {  
            xx m = w;  
            int x1 = m.s[--m.pos];  
            int x2 = m.s[--m.pos];  
            m.s[m.pos++] = x2 / x1;  
            m.pre = head;  
            m.op = 3;  
            p[end++] = m;  
        }  
  
        if (w.pos > 0)  
        {  
            xx m = w;  
            int x = m.s[--m.pos];  
            m.s[m.pos++] = x;  
            m.s[m.pos++] = x;  
            m.pre = head;  
            m.op = 4;  
            p[end++] = m;  
        }  
        ++head;  
    }  
    printf("-1\n");
}  
  
int main()  
{  
    while (~scanf("%d %d", &a, &b)) 
	{
		if (a==0) 
		{
			if (b==0) printf("0\n");
			else
				printf("-1\n");
		}
		else
		 find(); 
 	}
    return 0;  
}  


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值