Seven-segment Display 贪心选择,快速判断能否有解

https://csacademy.com/contest/round-39/task/seven-segment-display/

可以知道,只有1是无解

而且肯定是选出来的位数约小越好。

位数 = (k + 6) / 7,因为总是可以通过买7来最大化缩小位数

然后枚举每一位选什么,选的时候,需要的是,(k - cost + 6) / 7应该是比之前少一位的。这就是合法的。

选一个最小的合法的数字即可。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
int num[22];
int a[232];
vector<int> vc;
bool dfs(int lef, int pre) {
    if (!lef) return true;
    if (lef == 1) return false;
    for (int i = 0; i <= 6; ++i) {
        if (lef >= num[a[i]] && ((lef - num[a[i]] + 6) / 7) == pre - 1) {
            vc.push_back(a[i]);
            if (dfs(lef - num[a[i]], pre - 1)) return true;
            vc.pop_back();
        }
    }
    return false;
}
void work() {
    a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 4, a[4] = 6, a[5] = 7, a[6] = 8;
    num[1] = 2, num[7] = 3, num[4] = 4, num[2] = 5, num[0] = 6, num[8] = 7;
    num[6] = 6;
    int k;
    scanf("%d", &k);
    if (k == 1) {
        cout << -1 << endl;
        return;
    }
    if (k <= 7) {
        for (int i = 0; i <= 6; ++i) {
            if (k == num[a[i]]) {
                printf("%d
", a[i]);
                return;
            }
        }
    }
    int sel = (k + 6) / 7;
    for (int i = 1; i <= 6; ++i) {
        vc.push_back(a[i]);
        if ((k - num[a[i]] + 6) / 7 == sel - 1) {
            if (dfs(k - num[a[i]], (k - num[a[i]] + 6) / 7)) {
                for (int i = 0; i < vc.size(); ++i) {
                    printf("%d", vc[i]);
                }
                return;
            }
        }
        vc.pop_back();
    }
    printf("-1
");
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7242784.html