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