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 之外开发思路的好的方向,考场上可以很好区分层次。

完结撒花

相关推荐
誰能久伴不乏1 小时前
桌面客户端的运行日志系统:SQLite 分块 + 独立写线程 + 文本降级
数据库·c++·qt·架构·sqlite
choumin10 小时前
C++中万能引用与std::forward的作用和用法
c++·万能引用·std forward
下一站春风里11 小时前
位运算完整学习笔记:按位与(&)+ 异或(^)
开发语言·c++·算法
努力努力再努力wz14 小时前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
划破黑暗的第一缕曙光14 小时前
[C++]:4.模板
c++·template·模板·函数模版·类模版
十五年专注C++开发14 小时前
pybind11:一个跨C++和Python平台的编程库
开发语言·c++·python·pybind11
CodeYp201915 小时前
第11讲:stack 和 queue
开发语言·c++·queue·stack
沫璃染墨15 小时前
《Qt从零入门系列(十五):Qt线程安全与锁机制详解——从QMutex到RAII与读写锁实战》
开发语言·c++·qt·安全·交互·线程·qt6.3
hetao173383715 小时前
2026-10-25 hetao1733837 的刷题记录
c++·算法
fqbqrr16 小时前
2610C++,UI复合技术在窗口中绘画字体图标
c++·ui