我如何解决代码力121A

How can I solve codeforces 121A?

本文关键字:代码 121A 解决 何解决      更新时间:2023-10-16

我已经尝试解决codeforces问题121A

http://codeforces.com/problemset/problem/121/A

但是它给了我时间限制超过测试14

我想到的是生成所有可能的幸运数字,直到范围10^9,然后通过在可能性中寻找它来评估给定范围内所有数字的下一个(),然后我把它们加起来。我知道这是一种低效的方式,但我能修改一些东西来提高复杂性吗?有什么建议吗?

下面是我的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
long long int Next(long long int x, vector <long long int> vec , int &i){
    for (i ; i < vec.size(); i++){
        if (vec[i] >= x){
            return vec[i];
        }
    }
}
void Generate(int size, vector <long long int> &v , string s = "" ){
    if (size == 0){
        long long int intStr = strtoll(s.c_str(), NULL, 10);
        v.push_back(intStr);
        return;
    }
    Generate(size - 1,v, s + "4");
    Generate(size - 1,v, s + "7");
}
long long int Sum(long long int l, long long int r,vector <long long int> vec){
    long long int sum = 0;
    int index = 0;
    for (long long int i = l; i <= r; i++){
        sum += Next(i,vec,index);
    }
    return sum;
}
int main(){
        long long int l, r;
        cin >> l >> r;
        vector <long long int> vec;
        for (int i = 1; i <= 10; i++){
            Generate(i,vec,"");
        }

        cout << Sum(l, r, vec);

}

Next总是从列表开头查找下一个值;一旦你找到了第一个数字,你就不需要再搜索了。

注意您生成了整个列表,无论您需要的列表有多少。

在生成列表时,您构建字符串只是为了将它们解析为数字,这可能比只做简单的算术要慢。

Generate似乎重复了很多工作;例如,必须重新生成所有9位数的数字才能得到10位数的数字

您的代码中不需要Next()函数。只需修改Sum函数,其运行时间约为30 ms。首先把幸运数字按升序排序。假设x是第一个幸运数字,即>=l and <=r。因此,x将是[l,x]范围内所有数字的next()值。我们有x-l+1这样的数字,他们会把(x-l+1)*x加起来。在我们将其添加到sum之后,x现在变成了新的l。继续这个过程,直到x>r,此时我们将(r-l+1)*x添加到sum

代码:

long long int Sum(long long int l, long long int r, vector <long long int> vec){
    long long int sum=0;
    int index=0;
    sort(vec.begin(), vec.end());
    for(long long int i=0; i < vec.size(); i++){
        if(vec[i]>=l && vec[i]<=r) {
            sum+=(vec[i]-l+1)*vec[i];
            l=vec[i]+1;
        }
        else if(vec[i]>=l && vec[i]>r) {
            sum+=(r-l+1)*vec[i];
            break;
        }
    }
    return sum;
}

我有一个python实现,它对sum函数使用相同的概念,但您可以实现下一个函数,该函数在O(n)中运行,其中n是数字的长度。代码如下:

def next(n,k):
 s = n
 n = int(n)
 if int("4"*k)>=n:
    return "4"*k
 elif int("7"*k)<n:
    return "4"*(k+1)
 elif 4<int(s[0])<7:
    return "7"+"4"*(k-1)
 if not s[1:]=="":
    a = next(s[1:],k-1)
    if s[0]=="4":
        if len(str(a))==k:
            return "7"+a[1:]
        else:
            return "4"+a
    else:
            return "7"+a
 else:
    return "7"

这里n是字符串格式,k是该字符串的长度。