院赛1013(A number game)

A number game

Time Limit:1000MS  Memory Limit:65536K
Total Submit:69 Accepted:7

Description

You've designed a computer and implemented all the common arithmetic operators: addition, subtraction, multiplication and integer division. However, your budget was very limited, so you could only afford to place a single register in the computer. The register can store any non-negative integer value. Since there is only one register, there is no need to identify the store location or the operands of each operation or its result. The programming language has four instructions: '+', '-', '*' and '/'. Each instruction performs the corresponding operation using the value in the register as both its parameters. It then stores the result in the same register, overwriting the previous content.
A program for your computer is a sequential list of zero or more instructions. You want to show that, even with its limitations, your newly constructed computer is powerful. You will be given two ints s and t. Return the shortest program that finishes with a value of t in the register if it contained s before executing. If there is more than one possible answer, return the one that comes earliest lexicographically. If there is no program that can do the job, return ":-(" (quotes for clarity) instead.

 

Input

There are at most 100 cases,each case one line contain 2 space seperated integers S and T. (1 <= S,T <= 10^9)

Output

Output the shortest program that finishes with a value of t in the register if it contained s before executing. If there is more than one possible answer, return the one that comes earliest lexicographically. If there is no program that can do the job, return ":-(" (quotes for clarity) instead.

Sample Input


7 392
7 256
4 256
7 9


Sample Output


+*+
/+***
**
:-(


Source

 

 

 

代码有很多地方可以简化
RE无数次,MLEn次。。。。。
我这里当A<B时分两类讨论的,其实还不如直接bfs。。。。。

 

 

CODE:

/*BFS*/
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
bool mark[1000];//剪枝下,主要为了排除1*1=1的恶心循环,会MLE
struct px
{
	char path[1000];//路径储存
	__int64 v;
	int l;
};
struct px s; 
__int64 A,B;
char ans1[1005],ans2[1005];//最终路径储存
queue<px>Q;
int flag=0,len;
void bfs()
{
	struct px t,p;
	while(!Q.empty())
		Q.pop();
	Q.push(s);
	while(!Q.empty())
	{
		t=Q.front();
		Q.pop();
		if(t.v==B)
		{
			flag=1;
			if(t.l<len)
			{strcpy(ans1,t.path);len=t.l;}
			else if(t.l==len)
			{
				if(strcmp(t.path,ans1)<0)
					strcpy(ans1,t.path);
			}
			//puts(t.path);
			break;
		}
		if((t.v*t.v)<=B)//一定要把*放在前面,因为长度相等时要输出字典序最小
		{
			if((t.v*t.v)<900)
			{
				if(!mark[t.v*t.v])
				{
					mark[t.v*t.v]=true;
					p=t;
					p.path[p.l++]='*';
					p.path[p.l]='/0';
					p.v*=p.v;
					Q.push(p);
				}
			}
			else
			{
				//mark[t.v*t.v]=true;
				p=t;
				p.path[p.l++]='*';
				p.path[p.l]='/0';
				p.v*=p.v;
				Q.push(p);
			}
		}
		if(t.v+t.v<=B)
		{
			if((t.v+t.v)<900)//可以简化,这里很累赘
			{
				if(!mark[t.v+t.v])
				{
					mark[t.v+t.v]=true;
					p=t;
					p.path[p.l++]='+';
					p.path[p.l]='/0';
					p.v+=p.v;
					Q.push(p);
				}
			}
			else
			{
				//mark[t.v+t.v]=true;
				p=t;
				p.path[p.l++]='+';
				p.path[p.l]='/0';
				p.v+=p.v;
				Q.push(p);
			}
		}
	}
	return;
}
int main()
{
	while(scanf("%I64d%I64d",&A,&B)!=EOF)
	{
		if(B==1)
		{printf("//n");continue;}
		memset(mark,false,sizeof(mark));
		ans1[0]='/0';
		ans2[0]='/0';
		flag=0;
		len=99999999;//初始化
		if(A>B)
		{
			mark[1]=true;
			s.v=1;
			s.l=1;
			s.path[0]='/';
			s.path[1]='/0';
			bfs();
			if(!flag)
				printf(":-(/n");
			else
				printf("%s/n",ans1);
		}
		else
		{
			flag=0;
			s.v=A;
			if(A<900)
				mark[A]=true;
			s.path[0]='/0';
			s.l=0;
			bfs();
			if(flag)
				strcpy(ans2,ans1);
			memset(mark,false,sizeof(mark));
			flag=0;
			mark[1]=true;
			s.v=1;
			s.l=1;
			s.path[0]='/';
			s.path[1]='/0';
			bfs();
			if(flag)//重点注意,WA了无数次,对第一次有没有找到分类讨论
			{
				if(ans2[0]!='/0')
				{
					if(strlen(ans1)<strlen(ans2))
						printf("%s/n",ans1);
					else if(strlen(ans1)>strlen(ans2))
						printf("%s/n",ans2);
					else
					{
						if(strcmp(ans1,ans2)<0)
							printf("%s/n",ans1);
						else
							printf("%s/n",ans2);
					}
				}
				else
					printf("%s/n",ans1);
			}
			else
			{
				if(ans2[0]!='/0')
					printf("%s/n",ans1);
				else
					printf(":-(/n");
			} 
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__简言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值