您的位置:首页 > 其它

sicily 1050 Numbers & Letters

2013-10-19 00:53 381 查看
思路说明:

回溯的思想,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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: