“21 天好习惯”第一期-5

题目链接

https://ac.nowcoder.com/acm/contest/8827/F

题意

给出一定数量的火柴棍,将这些火柴棍按照七段码形式摆放组成数字 A
A k = a 1 a 2 . . . a k ‾ 1 ∣ a 1 2 ∣ a 1 a 2 . . . k ∣ a 1 a 2 . . . a k A_{k}=\overline{a_{1}a_{2}...a_{k}}\\ 1|a_{1}\\ 2|a_{1}a_{2}\\ ...\\ k|a_{1}a_{2}...a_{k} Ak=a1a2...ak1a12a1a2...ka1a2...ak
问满足以上情况的最大数字 A 称为魔法数字

思路

直接暴力枚举所有满足情况的数字 A ,随着k的增大,魔法数字的总数是不断减小的。以下证明

M k M_{k} Mk 为长度为 k k k 的所有满足情况的数字个数,同理 M k + 1 M_{k+1} Mk+1

A k A_{k} Ak 是长度为k的魔法数字,同理 A k + 1 A_{k+1} Ak+1

假设所有的长度为 k k k 的魔法数字能在末尾添加 ∀ x ∈ [ 0 , 9 ] \forall x \in[0,9] x[0,9] 使得 A k + 1 A_{k+1} Ak+1 成为魔法数字的话则有
M k ∗ 10 = M k + 1 ① A k + 1 = 10 ∗ A k + x , x ∈ [ 0 , 9 ] ∴ ( 10 ∗ A k + x )   %   ( k + 1 ) = 0 ∵ A k   %   k = 0 ⇒ A k = k ∗ Y ② ( 10 ∗ k ∗ Y + x )   %   ( k + 1 ) = 0 ③ M_{k}*10=M_{k+1}\quad\quad ①\\ A_{k+1}=10*A_{k}+x\quad, x\in[0,9]\\ \therefore (10*A_{k}+x)\ \% \ (k+1)=0\\ \because A_{k}\ \%\ k=0\Rightarrow A_{k}=k*Y \quad ②\\ (10*k*Y+x)\ \%\ (k+1)=0 ③\\ Mk10=Mk+1Ak+1=10Ak+x,x[0,9](10Ak+x) % (k+1)=0Ak % k=0Ak=kY(10kY+x) % (k+1)=0

由②的式子易证得对于 k ≥ 1 k\geq 1 k1 的所有情况 Y ≥ ( k + 1 ) Y\geq (k+1) Y(k+1) 等号只在 k = 1 k=1 k=1 时取得,这种情况暂不考虑
∴ Y = a ∗ ( k + 1 ) + b 1 ≤ b < ( k + 1 ) ∴ ③ 可 化 为 ( 10 ∗ k ∗ [ a ∗ ( k + 1 ) + b ] + x )   %   ( k + 1 ) ⇒ ( 10 ∗ k ∗ b + x )   %   ( k + 1 ) ⇒ ( 10 ∗ ( k + 1 ) ∗ b − 10 ∗ b + x )   %   ( k + 1 ) ⇒ ( x − 10 ∗ b )   %   ( k + 1 ) ⇒ ( X )   %   ( k + 1 ) [   ( x − 10 ∗ b + ( k + 1 ) ∗ m )   %   ( k + 1 ) = X   ] \therefore Y=a*(k+1)+b \quad 1\leq b\lt(k+1)\\ \therefore ③可化为(10*k*[a*(k+1)+b]+x)\ \%\ (k+1)\\ \Rightarrow (10*k*b+x)\ \%\ (k+1)\\ \Rightarrow (10*(k+1)*b-10*b+x)\ \%\ (k+1)\\ \Rightarrow (x-10*b)\ \%\ (k+1)\\ \Rightarrow (X)\ \%\ (k+1) [\ (x-10*b+(k+1)*m)\ \%\ (k+1)=X\ ]\\ Y=a(k+1)+b1b<(k+1)(10k[a(k+1)+b]+x) % (k+1)(10kb+x) % (k+1)(10(k+1)b10b+x) % (k+1)(x10b) % (k+1)(X) % (k+1)[ (x10b+(k+1)m) % (k+1)=X ]
则可以知道当 k k k 的值不断增大时,对应的 x x x 的选择就更少即①式中 M k ∗ 10 M_{k}*10 Mk10 不可能

M M M 关于 k k k 的二阶导数单调递减???)
即证得魔法数字的总数是不断减小的

代码

#include <bits stdc++.h>
#define sc(x) scanf("%lld", &amp;(x))
#define pr(x) printf("%lld\n", x)
#define mem(x, y) memset(x, y, sizeof(x))
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define pt putchar(10)
#define For(i, j, k) for (int i = (int)(j); i &lt;= (int)(k); i++)
#define Rep(i, j, k) for (int i = (int)(j); i &gt;= (int)(k); i--)
using namespace std;
typedef __int128 ll;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
const double PI = acos(-1);
const int INF = 0x3f3f3f3f;
ll m, n, i, j;
int c[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
ll ans[10010];
inline void write(__int128 x) {
    if (x &lt; 0) {
        putchar('-');
        x = -x;
    }
    if (x &gt; 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void dfs(int x, ll now, string s, int cost) {
    int i, j;
    if (x &gt; 0)
        ans[cost] = max(ans[cost], now);
    int start = 0;
    if (x == 0)
        start = 1;
    for (i = start; i &lt;= 9; i++) {
        if ((now * 10 + i) % (x + 1) == 0) {
            char ch = i + '0';
            dfs(x + 1, now * 10 + i, s + ch, cost + c[i]);
        }
    }
    return;
}
string t;
int main() {
    mem(ans, -1);
    dfs(0, 0, "", 0);
    cin &gt;&gt; t;
    if (t.size() &gt; 7)
        cout &lt;&lt; "-1" &lt;&lt; endl;
    else {
        n = atoi(t.c_str());
        write(ans[n]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值