Time Limit: 3 secs, Memory Limit: 32 MB
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.
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.
The output consists of N rows, each containing the best approximation of the target number using the 5 given numbers.
3 1 2 3 7 100 573 3 26 78 12 17 30 67 69 58 22 2 929
573 30 923
题目分析
深搜,题目大意是给定五个数和目标值,要求5个(或部分)数通过加减乘除(中间结果必须是整数),获得目标值,
不能获得则返回最接近且小于目标值的数
大概做法是
在num个可以用的数中,每次取第i个和第j个数,
将运算结果放到第i个数中,将最后一个可用的数放到第j个数
WA的原因有
一,可以不用全部数参与运算,所以每次迭代前要查看是否能获得最佳答案
二,我是开了个变量min来存储最佳答案与target的差值,通过取最小来更新
一开始取了0,没注意到target可以为0,后来改成一个较大的数据就可以了
三,做除法前确定除数非零,结果要为整数
#include <stdio.h> int digit[5]; int target; int min; void dfs(int num) { for (int i = 0; i < num; ++i) { if (digit[i] <= target) min = min < target-digit[i] ? min : target-digit[i]; } if (num == 1) return; for (int i = 0; i < num-1; ++i) { for (int j = i+1; j < num; ++j) { if (min == 0) return; int temp1 = digit[i]; int temp2 = digit[j]; digit[j] = digit[num-1]; digit[i] = temp1+temp2; dfs(num-1); digit[i] = temp1-temp2; dfs(num-1); digit[i] = temp2-temp1; dfs(num-1); digit[i] = temp1*temp2; dfs(num-1); if (temp2 && temp1%temp2==0) { digit[i] = temp1/temp2; dfs(num-1); } if (temp1 && temp2%temp1==0) { digit[i] = temp2/temp1; dfs(num-1); } digit[i] = temp1; digit[j] = temp2; } } } int main() { int num; scanf("%d", &num); for (int i = 0; i < num; ++i) { scanf("%d%d%d%d%d%d", &digit[0], &digit[1], &digit[2], &digit[3], &digit[4], &target); min = 1000000; dfs(5); printf("%d\n", target-min); } }