CSP2024-J T3小木棍

这题作为 JJJ 组 第三题 起着承前启后的作用,在往年真题里难度排行靠前,需要着一些思维

题目再现

分析题目

考虑可行性

我们思考是否存在数字无法被表示,容易发现

一位数字时需要的木棍数分别为 6,2,5,5,4,5,6,3,7,6{6,2,5,5,4,5,6,3,7,6}6,2,5,5,4,5,6,3,7,6

显然如果木棍数为 111 无法组成

显然两位可重复数字可以组成的数字有 4,144,144,14 (其中每个整数皆可到达)

显然我们可以在每两位数字后补一个数字 ,木棍数到达范围 6,216,216,21

从而易得,其后的每个数字都可以用木柴拼得

考虑最小

我们发现,当取尽可能多 111 时可以使组成数字尽可能大,取尽可能多 888 可以使组成数字尽可能小,根据上面的可行性证明, nnn 位数字可以取得 2n,7n2n,7n2n,7n ,由此我们可以求得当前木棍数可以得到的最小数字位数 len=⌊(s+6)/7⌋len=\lfloor (s+6)/7 \rfloorlen=⌊(s+6)/7⌋ 。

考虑填数字

容易想到的,我们要保证每一位数字取完后,剩下的木棍数还满足 (s′+6)/7<=len−1(s'+6)/7 <=len-1(s′+6)/7<=len−1 (len为当前确认的最小位数)。

从这条思路出发,我们从头开始,对每一位数字从 0~9 进行枚举 ,满足上式,则取之,就可以得到最优解。

考虑下界

我们发现,此时还有 s′>=(len−1)∗2s'>=(len-1)*2s′>=(len−1)∗2 的约束,但是由于我们尽可能往最短的位数靠近,且一定满足上界的判定(开头已经取了最大)。由此,我们只要考虑最后一位数字的合法性即可。

参考代码

cpp 复制代码
//枚举 查看大致逻辑
//发现位数技巧 构造 
#include<bits/stdc++.h>
using namespace std;
int n;
int f[10]={6,2,5,5,4,5,6,3,7,6};
int g[8]={0,-1,1,7,4,2,6,8};
string s;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        s="";
        cin>>n;
        int len=(n+6)/7;
        if(n<=7)
        {
            cout<<g[n]<<endl;
            continue;
        }
        for(int i=1;i<=len;i++)
        {
            int j=(i==1?1:0);
            for(;j<=9;j++)
            {
                int now=n-f[j];
                if((now+6)/7+i>len||now<0)
                    continue;
                s+=(j+'0');
                n-=f[j];
                break;
            }   
        }
        cout<<s<<endl;
    }
     
}

巧姐

从贪心的角度去看,我们想要取尽可能多的 888 ,满足位数最少。我们发现,当取得一位 888 时,剩下的数字必然是 888 (由公式中除法可知),所以我们的组合后面一定是一串 888 (如果有的话)。

所以我们可以对木柴数进行枚举,根据对 777 的余数进行分类讨论。

此处不多赘述,上图,可以参考洛谷题解前几篇

结尾

这题提供了多种解法,是除了 dp 之外开发思路的好的方向,考场上可以很好区分层次。

完结撒花

相关推荐
t-think2 小时前
C++ string 类(上)—— string类初识与常用接口详解
开发语言·c++
cpp_learners3 小时前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
开发语言·c++·责任链模式
郝学胜_神的一滴3 小时前
C++11 工程级应用 12:编译期类型魔法,干掉重复与臃肿的代码
c++·visual studio
David猪大卫4 小时前
【C++修炼】哈希表的实现
数据结构·c++·笔记·学习·算法·哈希算法·散列表
广州山泉婚姻4 小时前
列表初始化:C++11全新初始化体系
c++·人工智能
莫生灬灬4 小时前
灵码 LingBuilder:用中文写代码,确定性生成真实 C++ 工程(开源)
c++·开源·mfc
浅念-4 小时前
C++ Protobuf 入门实战:基于通讯录项目吃透proto3语法与序列化
linux·服务器·网络·c++·protobuf·proto·proto3
汉克老师6 小时前
CSP-J 初赛(以满分为目标):第三十九课《数学与逻辑②——阶乘、排列数与组合数:公式到底从哪里来?》
c++·csp-j·小学生·学c++编程
水饺编程6 小时前
第5章,[Win32 章节] :在平面直角坐标系中描点
c语言·c++·windows·visual studio
linx2956 小时前
单元九 · 零基础路线图-第 7–9 周·类与 RAII
c语言·开发语言·数据结构·c++·嵌入式硬件·算法