x的倍数

问题描述

假设给定一个从l到r的范围,我们被要求找出所有数字都是x的倍数的数字的计数。 x可以是1到9之间的任何数字。例如,取l = 20和r = 40且x = 2,则所需的数字是20、22、24、26、28、40,因为x的倍数是0、2、4 ,6,8。

我已经为此编写了代码。它针对某些测试用例运行。我不知道为什么大多数测试用例都给出错误的答案。

约束:1

我的代码

  #include<bits/stdc++.h>
 using namespace std;
 #define ll long long int

 ll s1(vector<string> &v,ll N)
 {

ll i,j,n = v.size(),ans = 0;
string ss = "",s = "";

for (i = 0; i < n; i++)
{
    s += v[i];
}
ss = to_string(N);

ll d = ss.length(),f = 0,x = n - 1,y = 1;


for (i = 1; i < d; i++)
{
    if (i == 1)
    {
        ans += x;
        y = x;
        continue;
    }
    y = y * n;
    ans += y;
}
ll z = 0;

for (j = 0; j < d; j++)
{
    f = 0; 

    for (i = 0; i < s.length(); i++)
    {
        if (z == 0)
        {
            z++;
            continue;
        }
        
        if (s[i] < ss[j])
        {

            ans += pow(n,d - (j + 1));
            z++;
        }
        else if (s[i] == ss[j])
        {
            z++;
            f = 1;
            break;
        }
    }
    if (!f)
    {
        break;
    }
}
ans += f;

return and;
}

int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);

int t;
cin >> t;

while (t--)
{
    ll l,r;
    ll k,i,g;

    cin >> l >> r >> k;
    vector<ll> v1;

    ll x = 0;
    while (x <= 9)
    {
        v1.push_back(x);
        x = x + k;
    }

    vector<string> s;

    for (i = 0; i < v1.size(); i++)
    {
        g = v1[i];
        char c = g + '0';
        string d(1,c);
        s.push_back(d);
        //  cout << D[i] << " ";
    }

    cout << s1(s,r) - s1(s,l - 1) << '\n';

}

 }

有人可以告诉我这个问题的更好逻辑吗?

解决方法

  1. 使用动态编程,我们可以编写函数f(x,d),该函数为我们提供范围[0,x]中的数字,以使每个数字都是d的倍数。
  2. dp状态:[position in X][is our number prefix == X prefix?]
  3. 将使用log10(X) * 2空间
  4. 开始状态显然是[0][1]
  5. 然后,我们只需填写dp表,使用递归尤其容易,在此我们只需检查可以添加的下一位数字即可满足所有条件
  6. 因此,如果我们删除常量,则此类dp函数的总复杂度将为O(log10(X) * 2 * 10)或仅为O(log N)
  7. 然后答案就是f(R,x)-f(L-1,x)

示例代码(C ++):

#include <bits/stdc++.h>
using namespace std;
#define ll long long

ll dp[22][2]; //[position in X][is our number prefix == X prefix?]

ll do_dp(vector<int>&digits,int k,int pos = 0,bool isEq = true)
{
    if(pos >= digits.size())return 1;
    if(dp[pos][isEq] != -1)return dp[pos][isEq];

    dp[pos][isEq] = 0;
    for(int d = 0; d <= (isEq ? digits[pos] : 9); d++) //d is next digit
        if(d % k == 0) //multiple of k
        dp[pos][isEq] += do_dp(digits,k,pos+1,isEq && d == digits[pos]);

    return dp[pos][isEq];
}

ll solve(ll x,int k)
{
    vector<int>digits;
    while(x > 0){
        digits.push_back(x%10);
        x/=10;
    }
    reverse(digits.begin(),digits.end());
    memset(dp,-1,sizeof dp);
    return do_dp(digits,k);
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    ll t,l,r,k;
    cin>>t;
    while(t--)
    {
        cin>>l>>r>>k;
        cout<<solve(r,k) - solve(l-1,k)<<"\n";
    }
}