Time Limit: 3 secs, Memory Limit: 32 MBios
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.app
The output consists of N rows, each containing the best approximation of the target number using the 5 given numbers.post
3 1 2 3 7 100 573 3 26 78 12 17 30 67 69 58 22 2 929
573 30 923
#include <iostream> using namespace std; int target; int a[5]; int max_r; /* 本題的思路爲每次在5個數中選擇2個數,而後對其分別進行加減乘除運算, 在進行了每種運算以後,獲得一個數,用這個數覆蓋掉所選的2個數中 的其中一個,因爲等下的深度優先搜索的數組大小減一,且需掃描可用的數來肯定最大數 或者是否達到目標數,因此該其中一個爲i,而不能是j,由於若是是j的話,會出現n-1的狀況 使得該運算結果等下不可用的狀況。 另一個數用當前數組最後一個數覆蓋,使數的個數減一 而後進行深度優先搜尋,構建深度優先搜索樹,繼續進行以上運算直到計算獲得目標數,或者 只剩下一個數不能繼續進行運算爲止 */ void DFS(int n) { //掃描當前可用數組,其中包含上一步驟的運算結果在內 //肯定當前數組最大數 for (int i = 0; i < n; i++) { if (a[i] <= target && a[i] > max_r) { max_r = a[i]; } } //若是達到了目標數,直接返回 if (max_r == target) { return; } //若是數組大小爲1,不能繼續進行運算了,此時max_r等於該5個數進行運算 //獲得的小於目標數的最大數 if (n == 1) { return; } //從n個數中任意選擇兩個數進行4種運算,其中經過兩重循環,包含了全部可能的兩個數的狀況 for (int i = 0; i < n; i++) { for (int j = i+1; j < n; j++) { int a1 = a[i]; int a2 = a[j]; //覆蓋掉已經選擇了的兩個數i,j,從而繼續對其餘數(包括剛剛計算獲得的運算結果) //進行深度優先搜索 a[j] = a[n-1]; a[i] = a1 + a2; DFS(n-1); a[i] = a1 - a2; DFS(n-1); a[i] = a2 - a1; DFS(n-1); a[i] = a1 * a2; DFS(n-1); if (a2 != 0 && a1 % a2 == 0) { a[i] = a1 / a2; } else if (a1 != 0 && a2 % a1 == 0) { a[i] = a2 / a1; } DFS(n-1); //運算完後,使得i,j變回原來的數,以便進行下一輪循環 a[i] = a1; a[j] = a2; } } } int main() { int test; cin >> test; while (test-- > 0) { int value; for (int i = 0; i < 5; i++) { cin >> value; a[i] = value; } cin >> target; max_r = -100000000; DFS(5); cout << max_r << endl; } return 0; }