CSP-J 2024 T2 小木棍
题目大意
小 S 有 n 根小木棍,希望拼出一个正整数,满足如下条件:
- 拼出这个数恰好使用 n 根小木棍。
- 拼出的数没有前导 0。
- 在满足以上两个条件的前提下,这个数尽可能小。
思路
拼出0~9分别需要的木棍数量:
数字 | 所需木棍数 |
---|---|
0 | 6 |
1 | 2 |
2 | 5 |
3 | 5 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 3 |
8 | 7 |
9 | 6 |
求解思想:
- 因为拼出
8
所需的木棍最多(7根),所以用8
,可以使位数更少 - 在保证位数最少的前提下,还要尽可能把高位的数字变小(必须保证位数最小)
按照思想,可以找到这样的规律:
条件 | 构造方案 |
---|---|
n == 1 | 无解 |
n == 2 | 1 |
n == 3 | 7 |
n == 4 | 4 |
n == 5 | 2 |
n == 6 | 6 |
n == 7 | 8 |
n == 10 | 22 |
(特判除外)n % 7 == 0 | (n / 7)个8 |
(特判除外)n % 7 == 1 | 10 + ((n - 8) / 7)个8 |
(特判除外)n % 7 == 2 | 1 + ((n - 2) / 7)个8 |
(特判除外)n % 7 == 3 | 200 + ((n - 17) / 7)个8 |
(特判除外)n % 7 == 4 | 20 + ((n - 11) / 7)个8 |
(特判除外)n % 7 == 5 | 2 + ((n - 5) / 7)个8 |
(特判除外)n % 7 == 6 | 6 + ((n - 6) / 7)个8 |
代码
#include <iostream>
using namespace std;
string Solve(int n) {
if (n == 1)
return "-1";
if (n % 7 == 0)
return string(n / 7, '8');
if (n % 7 == 1)
return "10" + string((n - 8) / 7, '8');
if (n % 7 == 2)
return "1" + string((n - 2) / 7, '8');
if (n % 7 == 3)
return n == 3 ? "7" : n == 10 ? "22" : "200" + string((n - 17) / 7, '8');
if (n % 7 == 4)
return n == 4 ? "4" : "20" + string((n - 11) / 7, '8');
if (n % 7 == 5)
return "2" + string((n - 5) / 7, '8');
if (n % 7 == 6)
return "6" + string((n - 6) / 7, '8');
}
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
cout << Solve(n) << endl;
}
return 0;
}