当前位置: 首页 > news >正文

《CF525E Anya 和立方体》

题目描述

Anya 喜欢折叠和粘贴。今天,她决定这样做。

Anya 有n立方体排成一行,编号为1自n从左到右,上面写有自然数。她还k带有感叹号的贴纸。我们知道贴纸的数量不会超过立方体的数量。

Anya 可以在立方体上贴一个感叹号,并得到写在立方体上的数字的阶乘。例如,如果一个 cube 读取5,然后在粘贴后显示为5!,它等于120.

您需要帮助 Anya 数一数有多少种方法可以选择一些方块,然后最多粘在一些选定的方块上k感叹号,以便粘贴后写在所选立方体上的数字之和等于S.Anya 最多可以在每个立方体上贴上一个感叹号。你能做到吗?

如果两种方法具有相同的所选多维数据集集和同一组带感叹号的多维数据集,则认为这两种方式相同。

输入格式

输入的第一行包含三个以空格分隔的整数n,kS(1≤ n≤25,0≤ k≤ n,1≤ S≤1016)— Anya 拥有的立方体数量和贴纸数量,以及她需要获得的总和。

第二行包含n正整数一个​ (1≤一个​≤109)——写在立方体上的数字。输入中的多维数据集按从左到右的顺序描述,从第一个多维数据集开始。

多个多维数据集可以包含相同的数字。

输出格式

输出选择一定数量的立方体的方法数,并在其中一些立方体上贴上感叹号,使数字之和等于给定的数字S.

隐藏翻译

题意翻译

给你 n 个数,n≤25。 初始序列为 一个​,0≤ 一个​≤109。

你有 k 个 !,每个 ! 可以使序列中的一个数变成 一个​!。 (同一个数至多变一次)

例如 5!=120。

求:选出任意个数使他们和的等于 S 的方案数

输入格式

第一行 n,k,S

第二行 n 个数,分别代表 一个​。

输出

一行一个整数,选出数的合法方案数。

感谢 @s_a_b_e_r 提供的翻译。

输入输出样例

输入 #1复制

<span style="color:#404040"><span style="background-color:#fafafa">2 2 30
4 3
</span></span>

输出 #1复制

<span style="color:#404040"><span style="background-color:#fafafa">1
</span></span>

输入 #2复制

<span style="color:#404040"><span style="background-color:#fafafa">2 2 7
4 3
</span></span>

输出 #2复制

<span style="color:#404040"><span style="background-color:#fafafa">1
</span></span>

输入 #3复制

<span style="color:#404040"><span style="background-color:#fafafa">3 1 1
1 1 1
</span></span>

输出 #3复制

<span style="color:#404040"><span style="background-color:#fafafa">6
</span></span>

说明/提示

在第一个示例中,唯一的方法是选择两个立方体并在每个立方体上贴上一个感叹号。

在第二个示例中,唯一的方法是选择两个多维数据集,但不要在其中任何一个多维数据集上粘贴感叹号。

在第三个示例中,可以通过三种方式选择任何立方体,我们也可以选择粘贴或不在其上粘贴感叹号。因此,方法的总数为 6 种。

代码实现:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;

// 计算阶乘,注意处理溢出情况
LL factorial(LL x) {
    LL res = 1;
    for (LL i = 2; i <= x; ++i) {
        res *= i;
    }
    return res;
}

// 生成所有可能的组合及其和与使用的感叹号数量
void generate(vector<pair<LL, LL> >& cubes, map<LL, map<LL, LL> >& sums) {
    int n = cubes.size();
    for (int mask = 0; mask < (1 << n); ++mask) {
        LL sum_normal = 0;
        LL sum_fact = 0;
        int k_used = 0;
        
        for (int i = 0; i < n; ++i) {
            if (mask & (1 << i)) {
                sum_normal += cubes[i].first;
                sum_fact += cubes[i].second;
                k_used++;
            }
        }
        
        sums[sum_normal][k_used]++;
        if (sum_fact != sum_normal) {
            sums[sum_fact][k_used]++;
        }
    }
}

int main() {
    int n, k;
    LL S;
    cin >> n >> k >> S;
    
    vector<LL> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    
    // 预处理每个数的原始值和阶乘值(防止大数溢出)
    vector<pair<LL, LL> > cubes(n);
    for (int i = 0; i < n; ++i) {
        LL fact = (a[i] <= 20) ? factorial(a[i]) : a[i];
        cubes[i] = make_pair(a[i], fact);
    }
    
    // 分割数组为左右两部分
    int mid = n / 2;
    vector<pair<LL, LL> > left(cubes.begin(), cubes.begin() + mid);
    vector<pair<LL, LL> > right(cubes.begin() + mid, cubes.end());
    
    // 生成左右两部分的所有可能和
    map<LL, map<LL, LL> > left_sums, right_sums;
    generate(left, left_sums);
    generate(right, right_sums);
    
    // 合并结果,计算符合条件的方案数
    LL ans = 0;
    for (map<LL, map<LL, LL> >::const_iterator it1 = left_sums.begin(); it1 != left_sums.end(); ++it1) {
        LL sum_left = it1->first;
        const map<LL, LL>& left_k_counts = it1->second;
        
        LL target = S - sum_left;
        map<LL, map<LL, LL> >::const_iterator it2 = right_sums.find(target);
        if (it2 == right_sums.end()) {
            continue;
        }
        
        const map<LL, LL>& right_k_counts = it2->second;
        
        // 遍历所有可能的感叹号使用组合
        for (map<LL, LL>::const_iterator lk = left_k_counts.begin(); lk != left_k_counts.end(); ++lk) {
            for (map<LL, LL>::const_iterator rk = right_k_counts.begin(); rk != right_k_counts.end(); ++rk) {
                if (lk->first + rk->first <= k) {
                    ans += lk->second * rk->second;
                }
            }
        }
    }
    
    cout << ans << endl;
    return 0;
}

相关文章:

  • gt0_data_valid_in在rx接收端使用
  • python变量如何理解?
  • 计量表计的演进历程与技术变革:从机械到物联网时代
  • OpenSSH 服务配置与会话保活完全指南
  • Python----循环神经网络(Transformer ----Encoder-Decoder)
  • Prim算法剖析与py/cpp/java语言实现
  • 如何使用 Redis 实现排行榜功能
  • TailwindCSS v4 快速入门教程
  • 从SPDY到HTTP/2:网络协议的革新与未来
  • Camera相机人脸识别系列专题分析之一:人脸识别系列专题SOP及理论知识介绍
  • 实时技术对比:SSE vs WebSocket vs Long Polling
  • 25、web场景-【源码分析】-静态资源原理
  • 零基础设计模式——结构型模式 - 组合模式
  • 产业集群间的专利合作关系
  • Spring Cloud 详解:2025 最新技术与最佳实践
  • 【iOS(swift)笔记-11】App版本升级时本地数据库sqlite更新逻辑
  • 线下陪玩app小程序 陪玩同城搭子系统开发;
  • vue2使用element中多选组件el-checkbox-group,数据与UI更新不同步
  • 计算机网络-网络层
  • ROS云课三分钟-3D性能测试supertuxkart和游戏推荐等-国际象棋
  • 简网站建设流程步骤/广州关键词排名推广
  • 智能网站建设软件/东莞网站公司哪家好
  • 优秀个人网站/深圳做网站的公司
  • ace网站建设/企业培训师资格证
  • 支付网站招聘费分录怎么做/seo关键词快速提升软件官网
  • 海沧网站制作/实时军事热点