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

挺好的一道深搜题,用时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;
}                  
时间: 2024-10-24 11:32:19

Sicily 1050. Numbers & Letters的相关文章

SOJ 1050. Numbers &amp; Letters

题目大意:给出5个整数和4种运算(加法,减法,乘法和除法),选取其中的部分数作任意运算,使得值等于目标数或者最接近目标数.其中,除法只能整除,即商必须是整数. 解题思路:每次选取任意两个数,进行可行的运算,获得结果并且和目标数作比较.最后得出答案. 代码如下: 1 #include <iostream> 2 //#include <ctime> 3 #include <vector> 4 #include <climits> 5 using namespac

sicily 1050 深度优先搜索解题

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 ma

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T

(转)sicily题目分类

Sicily题目分类 ·         [数据结构/图论] 1310 Right-Heavy Tree   笛卡尔树相关,复杂度O(N)或O(NlogN). ·1426 Phone List         电话号码前缀检索,trie树相关. ·1443 Printer Queue      基本队列操作. ·1149 等价表达式         判断表达式是否等价(递归求解) ·1136 山海经             n长序列里求m次区间询问的最大连续子区间和.线段树/RMQ ·1252

[转]8 Regular Expressions You Should Know

Regular expressions are a language of their own. When you learn a new programming language, they're this little sub-language that makes no sense at first glance. Many times you have to read another tutorial, article, or book just to understand the "s

docker搭建wordpress

闲话少说,奉上干货 Author : woodman Version: 1.0 实验环境 系统:CentOS Linux release 7.2.1511 内核:Linux C7 3.10.0-327.el7.x86_64 软件源 163+epel yum -y install wget vim cd /etc/yum.repos.d/ rm -f ./* wget http://mirrors.163.com/.help/CentOS7-Base-163.repo rpm -ivh  http

走进ReactiveCocoa的世界

在学习ReactiveCocoa之前,先学习一下概念 ReactiveCocoa 是一套开源的基于Cocoa的FRP框架 .FRP的全称是Functional Reactive Programming,中文译作函数式响应式编程,是RP(Reactive Programm,响应式编程)的FP(Functional Programming,函数式编程)实现.说起来很拗口.太多的细节不多讨论,我们先关注下FRP的FP特征. 函数式编程 函数式编程,简单来说,就是多使用匿名函数,将逻辑处理过程,以一系列

使用ReactiveCocoa实现iOS平台响应式编程

使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Programming,响应式编程),在维基百科中有这样一个例子介绍: 在命令式编程环境中,a = b + c 表示将表达式的结果赋给a,而之后改变b或c的值不会影响a.但在响应式编程中,a的值会随着b或c的更新而更新. Excel就是响应式编程的一个例子.单元格可以包含字面值或类似"=B1+C1″的公式,

李炎恢PHP笔记

Print Echo print 输出 转型 $sum=0; $total=(float)$sum Isset()   unset()判断一个变量是否存在 $echo intval$sum 浮点型 Define(“total”,100); 常量一旦定义就不可更改 判断句 <?php If ($userAge>14){ Echo’内容’:} ?> <?php If ($userAge>14){ Echo’内容’:} Else{echo ‘wufawutian’}; ?>