UVa 817:According to Bartjens(DFS)

题目链接   https://vjudge.net/problem/UVA-817

题意:输入一个以等号结尾。前面只包含数字的表达式,插入一些加号、减号和乘号,使得运算结果等于2000.表达式里的整数不能有前导零(例如,0100和000都是非法的),运算符都是二元的(例如,2*-100*-10+0=是非法的),并且符合通常的运算优先级法则。输入数字个数不超过9。如果有多解按照字典序从小到大输出:如果无解,输出IMPOSSIBLE。例如,2100100=有3组解,按照字典序依次为2*100*10+0=、2*100*10-0=和2100-100=。(本段摘自《算法竞赛入门经典(第2版)》)

分析: 
枚举插入运算符的个数,进行DFS即可。计算表达式的值直接用两个栈解决。需要注意的是,貌似题目并没有要求按字典序输出,还有就是至少要插入一个运算符。
 

#include<cstring>
#include<algorithm>
#include<set>
#include<iostream>
#include<ctype.h>
#include<string>
using namespace std;
#define NUM 2000 
char y[4]={
'*','+','-','#'
};
set<string> res;
char str[10];
char temp[40];
int n,kase=1;

void print(char temp[])
{
	int l=strlen(temp);
	char temp1[10];
	int k=0;

	for(int i=0;temp[i]!='=';i++)
	{
		if(temp[i]!='#') 
		temp1[k++]=temp[i];
	}
    temp1[k++]='='; temp1[k++]='\0';
	if(res.count(temp1)==0)
	res.insert(temp1); 
}

bool check(char temp[])
{
	int a=0,b;
	if(temp[0]=='0'&&temp[1]=='#'&&isdigit(temp[2]))
    return false;
	int l=strlen(temp);
	for(int i=2;i<l-2;i++)
	{
		if((temp[i-1]=='+'||temp[i-1]=='-'||temp[i-1]=='*')&&
		(temp[i]=='0')&&(temp[i+1]=='#')&& 
		 (isdigit(temp[i+2])))
         return false;
	}
	return true;
}
int compute(char temp[])
{
	    int b[10];
        char c[10];//准备b,c数组分别来存储依次输入的数字与运算符字符 
        int k=0,l=0;
        int sum=0;


        for(int i=0;i<strlen(temp)-1;i++)// NOT =
        {
            if(isdigit(temp[i]))
            {

                b[k++]=temp[i]-48;
            }
            else if(temp[i]=='#')
            {
                
				b[k-1]=b[k-1]*10+temp[i+1]-48;
				i++;      
            }
            else 
            {
                c[l++]=temp[i];      
            }
        }

        for(int i=0;i<l;i++)
        {
        	if(c[i]=='*')
        	{
			 b[i+1]=b[i]*b[i+1];
        	
        	for(int j=i;j<l-1;j++)
        	c[j]=c[j+1]; 
        	for(int j=i;j<k-1;j++)
        	b[j]=b[j+1];
        	i--;
        	l--;
        	k--;
			}
        }
        
        sum=b[0];
        for(int i=0;i<l;i++) 
        {
            
            switch(c[i])//来判断输入的运算符。 
            { 
            case '+':
                sum=sum+b[i+1];
                break;
            case '-':
                sum-=b[i+1];
                break;
            }
        }
        return sum;   //输出最终结果。 
} 
void dfs(int d,int c)
{
	if(temp[d]=='=') return;//finished
	
	int k=strlen(temp);
	temp[d]=y[c];
	/*
	cout<<d<<endl;
	for(int i=0;i<strlen(temp);i++)
	cout<<temp[i];
	cout<<endl;
	cout<<check(temp)<<":"<<compute(temp)<<endl;*/
	if(check(temp)&&compute(temp)==NUM) 
	{
        print(temp);
	}
		for(int i=0;i<4;i++)
		{
			dfs(d+2,i);
		}

}

void process()
{
	memcpy(temp,str,sizeof(char)*n);
	n=strlen(str);
	res.clear();
	int k=0;
	int i;
	for(i=0;i<strlen(str)-2;i++)
	{ 
	  temp[k++]=str[i];
      temp[k++]='#';
	}
	temp[k++]=str[i++];
	temp[k++]=str[i++];

	  
	for(int i=0;i<4;i++)
	{
		dfs(1,i);
	}
	cout<<"Problem "<<kase++<<endl;
	if(res.size()>0)
	{
	   set<string>::iterator it;
	  for(it=res.begin();it!=res.end();it++)
	  cout<<"  "<<*it<<endl;
	}else
	{
  	cout<<"  IMPOSSIBLE"<<endl;	
	}
	
	
}

int main()
{
	do
	{
		gets(str);
		process();
	}while(!(strlen(str)==1&&str[0]=='=')); 
}

猜你喜欢

转载自blog.csdn.net/qiang_____0712/article/details/84170147
今日推荐