sicily 1050.Numbers & Letters

1050. Numbers & Letters

Constraints

Time Limit: 3 secs, Memory Limit: 32 MB

Description

In the early 80’s, a popular TV show on Dutch television was ‘Cijfers en Letters’ (Numbers and Letters). This game consisted of two game elements, in which the main goal was to outclass your opponent. Letters is a game in which you are given a number of letters with which you should form the longest Dutch word possible. Since Dutch is a very hard language to learn we will postpone implementation of this game element until after the contest. 
For the second game element ‘Numbers’ 5 different numbers are chosen, together with a target number. The aim is to use some arithmetic on (some of) the five numbers to form the target number. Each number can be used only once. It might not be possible to form the target number given the input numbers, in that case the largest number smaller than the target number that can be calculated should be given. The only mathematical operations allowed are: +, -, *, /.  All intermediate results should be integers, so division is not always allowed (e.g. (2*2)/4 is OK, but 2*(2/4) is not). 
Examples: 
- If the 5 numbers are 1, 2, 3, 7 and 100 and the target number is 573, the target number can be reached as follows: (((100-1)*2)-7)*3. -If the 5 numbers are 3, 26, 78, 12 and 17, and the target number is 30, the target number can be reached as follows: (78*3)-(12*17). 
- If the 5 numbers are 67, 69, 58, 22, 2, and the target number is 929, the target number cannot be reached, but the largest number smaller than the target number that can be reached is 923 = (22-(67-58))*(69+2). 
Your assignment is to write a program that calculates the best approximation from below of the target number using arithmetic on the 5 given numbers. Note that if it is not possible to reach the exact number, you should give the largest reachable number below the target number.

Input

The first line contains the number of runs, N. The next N lines consist of six numbers separated by a space. The first 5 numbers Mi, 1≤Mi≤100, are the numbers you can use to calculate the target number. The sixth number is the target number T, 0≤T≤1000.

Output

The output consists of N rows, each containing the best approximation of the target number using the 5 given numbers.

Sample Input

3
1 2 3 7 100 573
3 26 78 12 17 30
67 69 58 22 2 929

Sample Output

573
30 
923

其实这道题给3秒有多,直接深搜就好了,思路是5把5个数设置成5层,每层选两个数用5种操作(加减乘除+减法交换)合并成一个数,进入下一层.要注意的是除法除零问题还有中间变量尽量接近目标数的处理.不需要剪枝.

#include <bits/stdc++.h>
using namespace std;
long long number[10];
long long target;
long long ans;
int ok = 0;

long long add(long long a,long long b){
	return a+b;
}
long long sub(long long a,long long b){
	return a-b;
}
long long multi(long long a,long long b){
	return a*b;
}
long long divide(long long a,long long b){
	if(a<b) swap(a,b);
	if(b!=0&&a%b==0)
	return a/b;
	return -1;
}

void find(long long num[],int n){
	if(ok)
	return;
	
	if(num[0]<=target){
		ans = max(ans,num[0]);
		if(ans == target){
			ok=1;
			return;
		}
	}
	if(n==1)
	return;
	
	long long box[6];
	for(int i=0;i<n-1;i++){
		for(int j=i+1;j<n;j++){
			//补数组 
			for(int k=0,index=1;k<n;k++){
				if(k!=i&&k!=j)
				box[index++]=num[k];
			}
			//加法 
			box[0]=add(num[i],num[j]);
			find(box,n-1);
			//减法1
			box[0]=sub(num[i],num[j]);
			find(box,n-1);
			//减法2 
			box[0]=sub(num[j],num[i]);
			find(box,n-1);
			//乘法 
			box[0]=multi(num[i],num[j]);
			find(box,n-1);
			//除法 
			box[0]=divide(num[i],num[j]);
			if(box[0]!=-1)
			find(box,n-1);
			
		}
	}
}
int main(){
	int t;
	while(cin>>t){
		while(t--){
			ans=-1E9;
			for(int i=0;i<5;i++){
				cin>>number[i];
			}
			cin>>target;
			for(int i=0;i<5;i++){
				if(number[i]<=target)
				ans=max(ans,number[i]);
			}
			ok=0;
			find(number,5);
			cout<<ans<<endl;
		}
	}
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值