版本1:
/*
回溯思路是这样的,5个数,先任意找2个数进行加减乘除,把这2个数运算后的结果当做一个数,按相同的方法搜下去
把4个数任取2个然后合并成3个,再继续搜下去
注意!!无论是除法还是求余,都要先检查是否为0
注意!!此题的 + - * / 一共有五个选择,减法有两种,必须加上
注意!!被注释掉的那一部分results记录方法是不能用的,不知道为什么会产生runtime error
*/
/*
Passed all 3 test cases
Run Time: 0.21secs
Run Memory: 312KB
*/
#include <iostream>
#include <memory.h> //memset初始化
using namespace std;
long nums[5]; //1-100
long target; //0-1000
bool flag; //标志位,是否可得到target
//*****int results[1001];//数组,存储着可以产生的最大值
long result; //这里可以使用数组存储,不过开销较大
//加减乘除的结果
long add(long a, long b){
return a+b;
}
long sub(long a, long b){
if(a > b)
return (a - b);
else
return (b - a);
}
long multi(long a, long b){
return a * b;
}
long divi(long a, long b){
if(a<b){
long buf = b;
b = a;
a = buf;
}
if(b==0 || a%b!=0)
return -1;
else
return (a / b);
}
void comput(const long used[], int count){
if(count>=2 && !flag){
long buf[5];
long newNum[5];
for(int i=0; i<count; i++){
for(int j=i+1; j<count; j++){ //遍历所有选择两个词
long a = used[i];
long b = used[j];
for(int k=0, l=0; k<count; k++){ //没有用到的数字排好
if(k!=i && k!=j){
buf[l++] = used[k];
}
}
newNum[0] = add(a, b);
newNum[1] = sub(a, b);
newNum[2] = multi(a, b);
newNum[3] = divi(a, b);
newNum[4] = (-1) * newNum[1];
for(int k=0; k<5; k++){ //逐个检查新产生的4个数字
long bufNum = newNum[k];
if(bufNum != -1){
if(bufNum <= target){ //如果产生的不大于目标数字,记录之,如果就是目标,那就返回
//***** results[bufNum] = 1;
if(bufNum > result)
result = bufNum;
if(bufNum == target){
flag = true;
return;
}
}
buf[count-1-1] = bufNum;
comput(buf, count-1); //深入进一步搜索
}
}
}
}
}
}
int main()
{
int T;
cin >> T;
while (T>0){
for(int i=0; i<5; i++)
cin >> nums[i];
cin >> target;
flag = false;
//***** memset(results, 0, sizeof(int)*1001);
result = -2000000000;
for(int i=0; i<5; i++){
if(nums[i] <= target){ //如果产生的不大于目标数字,记录之,如果就是目标,那就返回
//***** results[nums[i]] = 1;
if(nums[i] > result)
result = nums[i];
if(nums[i] == target){
flag = true;
break;
}
}
}
if(!flag)
comput(nums, 5);
cout << result << endl;
/****** for(int i=1000; i>=0; i--){ //输出结果
if(results[i] == 1){
cout << i << endl;
break;
}
}******/
T--;
}
return 0;
}
版本2:
/*
将获取值的位置换了一下,在函数执行头那里了
*/
/*
Passed all 3 test cases
Run Time: 0.18secs
Run Memory: 312KB
*/
#include <iostream>
#include <memory.h> //memset初始化
using namespace std;
long nums[5]; //1-100
long target; //0-1000
bool flag; //标志位,是否可得到target
//int result[1001];
long result;
//加减乘除的结果
long add(long a, long b){
return a+b;
}
long sub(long a, long b){
if(a > b)
return (a - b);
else
return (b - a);
}
long multi(long a, long b){
return a * b;
}
long divi(long a, long b){
if(a<b){
long buf = b;
b = a;
a = buf;
}
if(b==0 || a%b!=0)
return -1;
else
return (a / b);
}
void comput(long used[], int count){
if(flag)
return;
if(used[0] <= target){ //如果产生的不大于目标数字,记录之,如果就是目标,那就返回
if(used[0] > result)
result = used[0];
// result[used[0]] = 1;
if(used[0] == target){
flag = true;
return;
}
}
if(count == 1)
return;
long buf[5];
for(int i=0; i<count; i++){
for(int j=i+1; j<count; j++){ //遍历所有选择两个词
long a = used[i];
long b = used[j];
for(int k=0, l=1; k<count; k++){ //没有用到的数字排好
if(k!=i && k!=j){
buf[l++] = used[k];
}
}
buf[0] = add(a, b);
comput(buf, count-1);
buf[0] = sub(a, b);
comput(buf, count-1);
buf[0] = buf[0] * (-1);
comput(buf, count-1);
buf[0] = multi(a, b);
comput(buf, count-1);
buf[0] = divi(a, b);
if(buf[0] != -1)
comput(buf, count-1);
}
}
}
int main()
{
int T;
cin >> T;
while (T>0){
for(int i=0; i<5; i++)
cin >> nums[i];
cin >> target;
flag = false;
result = -2000000000;
// memset(result, 0, sizeof(int)*1001);
for(int i=0; i<5; i++){
if(nums[i] <= target){ //如果产生的不大于目标数字,记录之,如果就是目标,那就返回
if(nums[i] > result)
result = nums[i];
// result[nums[i]] = 1;
if(nums[i] == target){
flag = true;
break;
}
}
}
if(!flag)
comput(nums, 5);
cout << result << endl;
/* for(int i=1000; i>=0; i--)
if(result[i] == 1){
cout << i << endl;
break;
} */
T--;
}
return 0;
}