CSP历年复赛题-P11229 [CSP-J 2024] 小木棍
原题链接:https://www.luogu.com.cn/problem/P11229
题意解读:求n根木棍拼出的最小数。
解题思路:
每个数字需要的木棍根数为:
数字      所需木棍根数
0    6
1    2
2    5
3    5
4    4
5    5
6    6
7    3
8    7
9    6
由于要拼出的数字尽可能小,那么所需相同根数的数字,越小越好,需要6根的有0和6,由于0不能在开头,因此都要保留,最终剩下可用的数字为:
数字    所需木棍根数
0    6
1    2
2    5
4    4
6    6
7    3
8    7
当然,优先用耗费木棍越多的数字越好,也就是优先用7根拼出8,作为数字的后缀,前缀就看剩下多少根木棍;
但是,并不一定先把所有的8都拼出来最好,还需要分情况讨论:
设m = n % 7, x = n / 7
1、如果m = 0,则拼出x个”8”是最好的;因为如果有一个不选”8”,以为要这7根要用于拼其他数字,至少变成了2位数,显然更大。
2、如果m = 1,如果x=0则无解输出”-1”;如果x>0则可以将8根拼出”10”再拼出x-1个”8”。
3、如果m = 2,用2根拼出”1”再拼出x个”8”;”1”用来开头是最小了。
4、如果m = 3,x=0时直接用3根拼出”7”;x=1时是10根可以拼出”78”也可以拼出”22”,显然”22”更好;x>1时可以用17根拼出”200”或者”788”或者”228”,显然”200”最好,再拼出x-2个”8”。没有必要再考虑24根的情况,因为24根至少也要拼成4个数字,开头”200”已是最佳。
5、如果m = 4,x=0时时直接用4根拼出”4”;x>0时先用11根拼出”20”优于”48”,再拼出x-1个”8”。
6、如果m = 5,先用5根拼出2,再拼出x个”8”。
7、如果m = 6,先用6根拼出6,再拼出x个”8”。
100分代码:
#include <bits/stdc++.h>
using namespace std;
void print8(string pre, int x)
{
    cout << pre;
    for(int i = 1; i <= x; i++) cout << 8;
    cout << endl;
}
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        cin >> n;
        int m = n % 7, x = n / 7;
        if(m == 0) print8("", x);
        else if(m == 1)
        {
            if(x == 0) cout << -1 << endl;
            else print8("10", x - 1);
        }
        else if(m == 2) print8("1", x);
        else if(m == 3) 
        {
            if(x == 0) cout << 7 << endl;
            else if(x == 1) print8("22", x - 1);
            else print8("200", x - 2);
        }
        else if(m == 4) 
        {
            if(x == 0) cout << 4 << endl;
            else print8("20", x - 1);
        }
        else if(m == 5) print8("2", x);
        else if(m == 6) print8("6", x);
    }
    return 0;
}
					