题目链接
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...ak1∣a12∣a1a2...k∣a1a2...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 ③\\
Mk∗10=Mk+1①Ak+1=10∗Ak+x,x∈[0,9]∴(10∗Ak+x) % (k+1)=0∵Ak % k=0⇒Ak=k∗Y②(10∗k∗Y+x) % (k+1)=0③
由②的式子易证得对于
k
≥
1
k\geq 1
k≥1 的所有情况
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)+b1≤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 ]
则可以知道当
k
k
k 的值不断增大时,对应的
x
x
x 的选择就更少即①式中
M
k
∗
10
M_{k}*10
Mk∗10 不可能
(
M
M
M 关于
k
k
k 的二阶导数单调递减???)
即证得魔法数字的总数是不断减小的
代码
#include <bits stdc++.h>
#define sc(x) scanf("%lld", &(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 <= (int)(k); i++)
#define Rep(i, j, k) for (int i = (int)(j); i >= (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 < 0) {
putchar('-');
x = -x;
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void dfs(int x, ll now, string s, int cost) {
int i, j;
if (x > 0)
ans[cost] = max(ans[cost], now);
int start = 0;
if (x == 0)
start = 1;
for (i = start; i <= 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 >> t;
if (t.size() > 7)
cout << "-1" << endl;
else {
n = atoi(t.c_str());
write(ans[n]);
}
}