信息学奥赛一本通 2113:【24CSPJ普及组】小木棍(sticks) | 洛谷 P11229 [CSP-J 2024] 小木棍

devtools/2025/2/4 10:40:35/

【题目链接】

ybt 2113:【24CSPJ普及组】小木棍(sticks)
洛谷 P11229 [CSP-J 2024] 小木棍

【题目考点】

1. 思维题,找规律

【解题思路】

解法1:找规律

该题为:求n根木棍组成的无前导0的所有可能的数值中的最小数值
要想使最值数值最小,首先考虑让数字位数尽量少。朴素地想,每位数字使用的木棍越多,数字位数越少。一位数字最多使用7根木棍,摆成“8”。
我们可以考虑,将n根木棍不断摆出数字“8”,看最后剩下几根木棍,再做处理。
每次摆出数字“8”用7根木棍,最后剩下的木棍数量为n%7

如果n%7 != 0,那么也可以理解为还差x=7-n%7个木棍,就可以摆出每位都是8的数字。
已知构成每种数字的木棍数,以及距离摆成8还差几根木棍(7减去数字的木棍数)

表1:
数字木棍数距离摆成8还差几根木棍
061
125
252
352
443
552
661
734
870
961

根据上表可知,n根木棍可以摆出的数值最小的数字的位数为 d = ⌈ n / 7 ⌉ d = \lceil n/7 \rceil d=n/7
,n为1时无法摆成数字。

如果n是7的倍数,那么就可以摆出 n / 7 = ⌈ n / 7 ⌉ n/7=\lceil n/7 \rceil n/7=n/7位8
如果n不是7的倍数,那么看在 ⌈ n / 7 ⌉ \lceil n/7 \rceil n/7位8中,去掉1~6根木棍后能否形成合法的无前导0的数字。
观察上表可知,1位"8"在去掉1~5根木棍后都可以剩下非0的数字。
如果需要去掉6根木棍

  • 如果是1位8去掉6根木棍,也就是n=1的情况,这种情况无法构成数字。
  • 如果是2位以上的8去掉6根木棍,那么可以第1位去掉1根,第2位去掉5根,可以得到合法的数字。

根据n%7的值分类讨论,假设数字总位数很大,看还差x根木棍就可以摆出 d d d位“8”时,如何在 d d d位“8”中取走x个木棍,可以使得剩下的木棍摆成的数值最小。总原则是:使高位数字尽可能小。

表2:
n%7x=7-n%7操作
0无操作
16最高位拿走5根变为1,第2位拿走1根变为0
25最高位拿走5根变为1
34最高位拿走2根变为2,第2位拿走1根变为0,第3位拿走1根变为0
43最高位拿走2根变为2,第2位拿走1根变为0
52最高位拿走2根变为2
61最高位拿走1根变为6

只要数字位数 d ≥ 3 d\ge 3 d3,都可以使用上述方法得到n根木棍摆出的最小数字。
对于数字位数 d ≤ 2 d\le 2 d2,也就是 1 ≤ n ≤ 14 1\le n\le 14 1n14的情况,可以手动枚举每种情况可以摆出的最小数字。总原则是:位数尽可能小。位数相同时,首位尽可能小。

表3:
木棍数量摆出的最小数字
1-1(无法摆出数字)
21
37
44
52
66
78
810
918
1022
1120
1228
1368
1488

对于每组数据,先输入n,再求出数字位数 d = ⌈ n / 7 ⌉ d=\lceil n/7 \rceil d=n/7
代码中使用公式: ⌈ a b ⌉ = ⌊ a − 1 b ⌋ + 1 \lceil \frac{a}{b} \rceil=\lfloor \frac{a-1}{b} \rfloor+1 ba=ba1+1

  • 如果数字位数 d ≤ 2 d\le 2 d2,则根据表3,直接通过木棍数量得出其可以构造出的最小数字。
  • 如果数字位数 d ≥ 3 d\ge 3 d3,则根据n%7的值以及表2,得到拼出的数字的前几位,后面的每位都是8。

【题解代码】

解法1:找规律

#include<bits/stdc++.h>
using namespace std;
#define N 100005
int minNum[20] = {0, -1 ,1 ,7 ,4 ,2 ,6 ,8 ,10 ,18 ,22 ,20 ,28 ,68 ,88};//minNum[i]:i根小木棍拼出有前导0的最小数字
int pn[7] = {0, 10, 1, 200, 20, 2, 6}, pd[7] = {0, 2, 1, 3, 2, 1, 1};//pn[i]:n%7==i时前几位摆出的数字 pd[i]:pn[i]的位数 
int main()
{int t, n, d;cin >> t;while(t--){cin >> n;//木棍数 d = (n-1)/7+1;//拼成的数字的总位数 if(d <= 2)cout << minNum[n] << endl;//如果n为1,拼不成数字,会输出-1 else{if(n%7 > 0)//只要n不是7的倍数,则需要通过pn输出前几位 cout << pn[n%7];for(int i = 1; i <= d-pd[n%7]; ++i)//pn[n%7]有pd[n&7]位,还需要输出d-pd[n%7]位8 cout << 8;cout << endl;}} return 0;
}

http://www.ppmy.cn/devtools/155976.html

相关文章

Hot100之图论

200岛屿数量 题目 思路解析 把访问过的格子插上棋子 思想是先污染再治理&#xff0c;我们有一个inArea&#xff08;&#xff09;函数&#xff0c;是判断是否出界了 我们先dfs&#xff08;&#xff09;放各个方向遍历&#xff0c;然后我们再把这个位置标为0 我们岛屿是连着…

WPF进阶 | WPF 数据绑定进阶:绑定模式、转换器与验证

WPF进阶 | WPF 数据绑定进阶&#xff1a;绑定模式、转换器与验证 一、前言二、WPF 数据绑定基础回顾2.1 数据绑定的基本概念2.2 数据绑定的基本语法 三、绑定模式3.1 单向绑定&#xff08;One - Way Binding&#xff09;3.2 双向绑定&#xff08;Two - Way Binding&#xff09;…

Java集合面试总结(题目来源JavaGuide)

问题1&#xff1a;说说 List,Set,Map 三者的区别&#xff1f; 在 Java 中&#xff0c;List、Set 和 Map 是最常用的集合框架&#xff08;Collection Framework&#xff09;接口&#xff0c;它们的主要区别如下&#xff1a; 1. List&#xff08;列表&#xff09; 特点&#xf…

【算法】回溯算法专题③ ——排列型回溯 python

目录 前置小试牛刀回归经典举一反三总结 前置 【算法】回溯算法专题① ——子集型回溯 python 【算法】回溯算法专题② ——组合型回溯 剪枝 python 小试牛刀 全排列 https://leetcode.cn/problems/permutations/description/ 给定一个不含重复数字的数组 nums &#xff0c;返…

【数据结构】_链表经典算法OJ:复杂链表的复制

目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;…

第一章,信息安全概述

什么是信息&#xff1f;------信息是通过施加于数据上的某种约定而赋予这些数据的含义。 什么是信息安全&#xff1f; ISO----->数据处理系统建立和采取技术、采取技术、管理的安全保护&#xff0c;用来保护计算机硬件、软件、数据不因为偶然的或恶意的原因遭受到破环。 美…

汽车自动驾驶AI

汽车自动驾驶AI是当前汽车技术领域的前沿方向&#xff0c;以下是关于汽车自动驾驶AI的详细介绍&#xff1a; 技术原理 感知系统&#xff1a;自动驾驶汽车通过多种传感器&#xff08;如激光雷达、摄像头、雷达、超声波传感器等&#xff09;收集周围环境的信息。AI算法对这些传感…

vscode技巧总结

“Tips and Tricks” lets you jump right in and learn how to be productive with Visual Studio Code. 官方技巧 Visual Studio Code Tips and Tricks 我发现的技巧 删除一个代码块的时候&#xff0c;先用 Ctrl Shift [ 折叠代码块&#xff0c;再选中然后删除&#xff…