• 11F:42点


    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    42是:

    ·组合数学上的第5个卡特兰数

    ·字符'*'的ASCII码

    ·钼的原子序数

    ·6与9的乘积结果的13进制表示

    ·生命、宇宙以及任何事情的终极答案

    ·以及……表达式(1+5)/2*(6-4)*7的值

    因此,小机器人Marvin发明了这个叫42点的小游戏。在这个游戏中,玩家会获得n个数。玩家需要使用'+'、'-'、'*'、'/'、'('、')'以及这n个数构成一个合法的中缀表达式,并使得该表达式的值为42。n个数之间的顺序可以改变。表达式运算过程中只能出现整数。

    由于过于抑郁,Marvin无力完成这个游戏,于是来找你帮忙。你的任务是对于给定的n个数,判断他们是否能根据上述游戏规则算出42。

    输入
    第一行为一个数n,1<=n<=6。
    第二行为n个数,每个数均为[1,13]范围内的整数。
    输出
    输出一行,若可以算出42则输出“YES”,否则输出“NO”(注意大小写)。
    样例输入
    6
    1 5 2 6 4 7
    样例输出
    YES

    代码:

     1 #include <iostream>
     2 #include <vector>
     3 #include <cmath>
     4 #include <algorithm>
     5 using namespace std;
     6 vector<int> ele;
     7 int n;
     8 
     9 bool dfs(int m){
    10     if(m == 1){
    11         if(ele[0] == 42)
    12             return true;
    13         return false;
    14     }
    15     for(int i = 0; i < m - 1; ++i)
    16         for(int j = i + 1; j < m; ++j){
    17             int t1 = ele[i], t2 = ele[j];
    18             ele[i] = t1 + t2;
    19             ele[j] = ele[m - 1];
    20             if(dfs(m - 1))
    21                 return true;
    22             ele[i] = t1 - t2;
    23             if(dfs(m - 1))
    24                 return true;
    25             ele[i] = t2 - t1;
    26             if(dfs(m - 1))
    27                 return true;
    28             ele[i] = t1 * t2;
    29             if(dfs(m - 1))
    30                 return true;
    31             if(t2 != 0 && abs(t1) % abs(t2) == 0){
    32                 ele[i] = t1 / t2;
    33                 if(dfs(m - 1))
    34                     return true;
    35             }
    36             else if(t1 != 0 && abs(t2) % abs(t1) == 0){
    37                 ele[i] = t2 / t1;
    38                 if(dfs(m - 1))
    39                     return true;
    40             }
    41             ele[i] = t1, ele[j] = t2;
    42         }
    43     return false;
    44 }
    45 
    46 int main(){
    47     cin >> n;
    48     int t;
    49     for(int i = 0; i < n; ++i){
    50         cin >> t;
    51         ele.push_back(t);
    52     }
    53   //  sort(ele.begin(), ele.end());
    54     if(dfs(n))
    55         cout << "YES" << endl;
    56     else
    57         cout << "NO" << endl;
    58 }

    备注:我坦白!这是上机练习的参考答案不是我写的代码。

    感觉看这道题的答案获得了很多启发。其实没有技巧,不用动归,搜索就可以。排序是没用的,所以那行我给注释掉了。

    数字的顺序是任意的,怎么体现呢?就是dfs里的两个循环,相当于每一次是随意从数列中挑两个数摘出来进行+-*的运算。枚举的时候没考虑对称的情况,所以对于不对称运算减和除就两种都dfs一下就好了!我最开始没看懂的是,从数列中挑出两个数,运算完了之后把结果填进了ele[i],那ele[j]为啥填了个ele[m-1]?

     其实就是因为两个数相加产生了一个空当,就非常巧妙的把最后一个数移到前面这个空当里,当然也可以把后面的所有数字整体往前移一位(which是时间上更复杂的,并且没有必要,因为数字的顺序是任意的),相当于就是缩短了序列,把ele[j]删掉了。i每次循环到最后一个数是m-1,所以这个序列就是越来越短的!我觉得还挺巧妙的qwq

  • 相关阅读:
    asyncio异步IO--协程(Coroutine)与任务(Task)详解
    python爬虫实战:利用scrapy,短短50行代码下载整站短视频
    深入理解Git的实现原理
    Upsource 代码审查工具安装及使用
    MAC MAMP集成环境安装 PHP 扩展
    千万数据量数据表分表实践
    设计模式:序言
    设计模式 行为型
    PHP5底层原理之变量
    PHP5底层原理之垃圾回收机制
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/13145108.html
Copyright © 2020-2023  润新知