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
挺好的一道深搜题,用时0.23s:
#include <iostream> #include <algorithm> #include <vector> #include <stdio.h> using namespace std; int target, max_possi;//目标数字以及最接近目标且小于目标的数字 bool is_ok;//是否已经找到目标 int add(int a, int b) {return a + b;}//定义加 int sub_posi(int a, int b) {return a > b ? a - b : b - a;}//定义返回正数的减 int sub_nega(int a, int b) {return a < b ? a - b : b - a;}//定义返回负数的减 int mul(int a, int b) {return a * b;}//定义乘 int divi(int a, int b) {//定义除 if ((b == 0 && a != 0) || (a == 0 && b != 0))//有且仅有一个为零返回零 return 0; else if (a == 0 && b == 0)//两个为零不能除 return 99999999; else { int aa = a > 0 ? a : -a;//找到绝对值方便比较模 int bb = b > 0 ? b : -b; if (aa % bb == 0) return a / b; else if (bb % aa == 0) return b / a; else return 99999999; } } void dfs(int a[], int size) { int i, j, k, b[5] = {0}, k1; for (i = 0; i < size; i++) {//查看目标是否已经达到 if (a[i] == target) { is_ok = true; return; } else { if (a[i] > max_possi && a[i] <= target) {//更新最大值 max_possi = a[i]; } } } if (size == 1) {//只剩一个数字的时候 if (a[0] > max_possi && a[0] <= target) { max_possi = a[0]; } return; } for (i = 0; i < size; i++) { for (j = i + 1; j < size; j++) { b[0] = add(a[i], a[j]);//加 for (k1 = 1, k = 0; k < size; k++) {//构造下一层的数组, 下同 if (k != i && k != j) b[k1++] = a[k]; } dfs(b, size - 1); if (is_ok) return; b[0] = sub_posi(a[i], a[j]);//返回正数的减 for (k1 = 1, k = 0; k < size; k++) { if (k != i && k != j) b[k1++] = a[k]; } dfs(b, size - 1); if (is_ok) return; b[0] = sub_nega(a[i], a[j]);//返回负数的减 for (k1 = 1, k = 0; k < size; k++) { if (k != i && k != j) b[k1++] = a[k]; } dfs(b, size - 1); if (is_ok) return; b[0] = mul(a[i], a[j]);//乘 for (k1 = 1, k = 0; k < size; k++) { if (k != i && k != j) b[k1++] = a[k]; } dfs(b, size - 1); if (is_ok) return; b[0] = divi(a[i], a[j]);//除 if (b[0] != 99999999) { for (k1 = 1, k = 0; k < size; k++) { if (k != i && k != j) b[k1++] = a[k]; } dfs(b, size - 1); if (is_ok) return; } } } } int main() { int case_num, i, num[5]; scanf("%d", &case_num); while (case_num--) { for (i = 0; i < 5; i++) { scanf("%d", &num[i]); } scanf("%d", &target); max_possi = -99999999; is_ok = false; dfs(num, 5); if (is_ok) printf("%d\n", target); else printf("%d\n", max_possi); } return 0; }