1 条题解

  • 0
    @ 2026-10-26 1:48:52

    思路与算法

    把区间统计改成F(B)-F(A-1),F(t)为不超过t的正Windy数数量。

    从最高位递归,记录剩余位位置pos、前一个有效数位previous,以及是否仍受上界约束tight。previous=10是尚未开始的哨兵。未开始且当前放0时仍保持10,不把补位0当作真实数位;否则只有第一位有效数字,或与前一位差的绝对值至少2时,才可转移。

    全部位结束后,previous不为10才计一种,排除整数0。非tight状态按pos和previous记忆化。

    正确性说明

    构造过程中previous始终是已经写出的最后一个真实数位,或者表示尚未开始。每次加入有效数字时检查与上一真实数字的差,恰好满足Windy数对每对相邻位的要求;前导补0不会引入额外约束。

    tight保证构造值不超过上界,结束时排除全0路径。每个正整数只有一个补齐到上界位数的数位序列,因此合法数恰计一次。故F准确,前缀差给出闭区间答案。

    复杂度

    十进制位数L≤10。缓存状态数O(L×11),每个枚举至多10个数字,时间O(L×11×10)。参考程序每次还清空15×11个缓存单元,含初始化为O(15×11+L×11×10)时间,空间O(15×11+L)。

    易错点

    不能把前导0视为上一位0,否则会错误排除许多一位数。条件是差的绝对值至少2,等于2允许。0不属于正Windy数;A=1需要F(0)=0。两组原站公开样例都已纳入评测,且需考虑端点相同的区间。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    vector<int> digit;
    ll memo[15][11];
    ll solve(int pos, int previous, bool tight) {
        if (pos < 0)
            return previous != 10;
        if (!tight && memo[pos][previous] != -1)
            return memo[pos][previous];
        int cap = tight ? digit[pos] : 9;
        ll answer = 0;
        for (int d = 0; d <= cap; ++d) {
            if (previous == 10 && d == 0)
                answer += solve(pos - 1, 10, tight && d == cap);
            else if (previous == 10 || abs(previous - d) >= 2)
                answer += solve(pos - 1, d, tight && d == cap);
        }
        if (!tight)
            memo[pos][previous] = answer;
        return answer;
    }
    ll count(ll n) {
        if (n <= 0)
            return 0;
        digit.clear();
        while (n) {
            digit.push_back(n % 10);
            n /= 10;
        }
        memset(memo, -1, sizeof(memo));
        return solve(digit.size() - 1, 10, true);
    }
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        ll a, b;
        cin >> a >> b;
        cout << count(b) - count(a - 1) << '\n';
    }
    
    • 1

    信息

    ID
    1643
    时间
    1000ms
    内存
    512MiB
    难度
    普及
    标签
    递交数
    1
    已通过
    1
    上传者