sicily 1050 Numbers & Letters

思路说明:

             回溯的思想,5个数,先任意找2个数进行加减乘除,把这2个数运算后的结果当做一个数,按相同的方法搜下去  把4个数任取2个然后合并成3个,再继续搜下去  

详细解释:

            任意找两个数,两重for循环,得到所有可能情况   保存中间结果,在dfs函数里,新建立一个长度5的int数组,其中第0位保存中间结果 ,

              其它依次保存选取两个数后剩下来的数   其中dfs时也要记录搜索的深度

易错点:

            题意中说some of,即不用5个数全参与运算,所以从一个到5个,

             只要计算出满足要求的值都是可以的  max的初始值设为-INF,在这个上面WA了好久,我问了师父才明白,

            参与运算后,虽然tar>=0,但是比tar小的运算结果不一定能够达到0或者-1一般的初始化值

个人历程:

         这一题一开始感觉用枚举,受了之前做的题目的影响,感觉就5个数,枚举一下顺序,操作数,优先级应该就可以了,

          写起代码来又很繁琐,多重循环到想吐,磕磕碰碰写出来,速度自己都看不下去,看了一位师兄的题解,又是搜索,本来像这种计算表达式的值,

           用栈比较好,可是操作数的顺序是变化的,我感觉不太好处理,中间结果又如何区别也是要考虑的问题


参考代码:

#include<iostream>
#include<stack>

using namespace std;

int a[5]; 
int _max=0;//记录小于等于target的运算出的最大值
int tar;

bool flag;
int add(int a,int b){return a+b;}
int sub(int a,int b){return a-b;}
int mul(int a,int b){return a*b;}
int div2(int a,int b)
{
    if(a<b)
    {
        a=a+b;
        b=a-b;
        a=a-b;
    }
    if( b==0 || a%b!=0)
            return -1;

    return a/b;
}

void dfs( int index[],int size )
{
	if(flag)
		return;
	if( index[0]<=tar && index[0]>_max )
	{
		_max=index[0];
		if(_max==tar){
			flag=true;
			return ;
		}
	}
   
      if(size==1)
          return ;

      int i,j,h,k;
      int num[5];
      for( i=0; i<size; i++ )
      {
         for( j=i+1; j<size; j++)
         {
               for( h=1,k=0; k<size; k++)
                 if( k!=i && k!=j)
                    num[h++]=index[k];
                num[0]=add(index[i],index[j]);
                dfs(num,size-1);
                num[0]=sub(index[i],index[j]);
                dfs(num,size-1);
                num[0]=-num[0];
                dfs(num,size-1);
                num[0]=mul(index[i],index[j]);
                dfs(num,size-1);
                num[0]=div2(index[i],index[j]);				
                if(num[0]!=-1)
                {
                  dfs(num,size-1);
                }
         }
      }

    
}
int main()
{
    int n,i,j;
   
    cin>>n;
  
    for( int s=0; s<n; s++)
    {
        for( i=0; i<5; i++)
           cin>>a[i];
		   cin>>tar;

		 _max=-1;
		 flag=false;

		 for(i=0; i<5; i++){
		       if( a[i]<=tar && a[i]>_max )
	            {
		         _max=a[i];
		        
	            }
		}
       
        
		
        dfs(a,5);
        cout<<_max<<endl;
    }
    
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值