「CSP-J 2024」小木棍 审核通过

lyh045 CSP-J2二等 2025-05-17 18:26:25 16

大致思路

1 先把每一个数字需要的木棍数列举出来

0:6
1:2
2:5
3:5
4:4
5:5
6:6
7:3
8:7
9:6

列出来后可以看到一些没必要留下来的数,删掉

剩下的

0:6
1:2
2:5
4:4
6:6
7:3
8:7
>注:0不能直接删去,后面有大用

2 简单打表

我们可以试试先列一些数字(建议从小到大:如1,2,3,4······)

1:-1 2:1 3:7 4:4 5:2 6:6 7:8 8:10 9:18 10:22 11:20 12:28 13:68 14:88

3 找规律

1) 因为8需要7根火柴,要的最多,所以许多答案里后面全是8

2) 先说结论:除1外,其他所有数都不输出-1

3) 再打表后 我们可以试着整一些其他数字,比如19

4) 先将19/7——————>2,设k=19%7——————>5

  1. 先输出和5匹配的项,查表可知是2,19/7得2,即在输出2个8

6)但这思路不对,因为上面打的表里7—14有许多不带8或只有1个8,这说明用这思路写会WA

7)不妨试试将每一个大于14的输入都分成2部分:1、最大的两位:我们知道这两位应当要最小,我们可以利用刚才打的表,将k(余数)+7后在查表输出。

2:“8”部分:将19/7后得2,但是只能输出(2-1)个,因为前面我们将k加了7(应当少输一个8)

在上面的输出中,我们将其分为两部分 先输出最小的前两位,后面跟一堆8,这样就可以做到输出最小的

4 解释第三步中的 2)

1 小于等于14的,除1外,都有数可对应

2 大于14的 无论如何,k+7都有指定的数,一定大于等于7,小于14,而这些查表都有指定的数

5 code

#include <bits/stdc++.h>

using namespace std;

int a[20] = { 0, -1, 1, 7, 4, 2, 6, 8, 10, 18, 22, 20, 28, 68, 88 };
int main() {
    freopen("sticks.in", "r", stdin);
    freopen("sticks.out", "w", stdout);
    int t;
    cin >> t;
    int f;
    for (int i = 1; i <= t; i++) {
        cin >> f;
        if (f <= 14) {
            cout << a[f] << '\n';
            continue;
        } else {
            int k = f % 7 + 7;
            f /= 7;
            f -= 1;
            cout << a[k];
            for (int j = 1; j <= f; j++) cout << 8;
            cout << '\n';
        }
    }
    return 0;
}

6 纠错(特判)

在思路中我们就有个问题当(k+7)=10时我们会输出22,但是后面会有8 依照思路我们会输出228,但实际上要输出200 即当(k+7)=10时要加个特判

ACcode

#include <bits/stdc++.h>

using namespace std;

int a[20] = { 0, -1, 1, 7, 4, 2, 6, 8, 10, 18, 22, 20, 28, 68, 88 };
int main() {
    freopen("sticks.in", "r", stdin);
    freopen("sticks.out", "w", stdout);
    int t;
    cin >> t;
    int f;
    for (int i = 1; i <= t; i++) {
        cin >> f;
        if (f <= 14) {
            cout << a[f] << '\n';
            continue;
        } else {
            int k = f % 7 + 7;
            f /= 7;
            f -= 1;
            int o[8];
            memset(o, 0, sizeof(o))if (a[k] > 10) {
                o[1] = a[k】 % 10}
            if (f >= 1)
                o[2] = 8;
            if (o[1] == 2 && 0[2] == 8) {
                cout << a[k] / 10;
                cout << 0 << 0;
                for (int j = 2; j <= f; j++) cout << 8;
                cout << endl;
            } else {
                cout << a[k];
                for (int j = 1; j <= f; j++) cout << 8;
                cout << endl;
            }
        }
    }
    return 0;
}
{{ vote && vote.total.up }}