RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1060191
Accepted
David
David
Asked:2020-12-18 17:06:46 +0000 UTC2020-12-18 17:06:46 +0000 UTC 2020-12-18 17:06:46 +0000 UTC

Yandex 的任务是在数组中找到随机数的总和

  • 772

我正在尝试从 Yandex 解决这个问题(见下文)

PS我看到了这篇文章,但不幸的是我没有找到我的问题的答案。 在此处输入图像描述

我有的问题:

  1. 我不确定我是否正确理解了任务的本质,我理解它的方式是我应该使用 RNG 来确定数组的大小并用随机值填充它,然后是随机元素的总和应该显示数组,但我是否正确理解了任务的本质?
  2. 如何控制资源限制?(以我的 Visual Studio 2019 为例)

我未完成的代码

#include <iostream>
#include <random>
#include <ctime>
#include <iomanip>
using namespace std;


class Random /*fold00*/
{
public:
    typedef int RandomValue;
    Random& operator = (int seed) { X = seed; return *this; }
    Random(int seed = 1) :X(seed) {};
    int operator()(int seed = 0)
    {
        const int MM = 2147483647;
        const int AA = 48271;
        const int QQ = 44488;
        const int RR = 3399;
        if (seed != 0) X = seed;
        X = AA * (X % QQ) - RR * (X / QQ);
        if (X < 0) X += MM;
        return X - 1;
    }
    // Не включая max
    int operator()(int min, int max)
    {
        return (*this)() % (max - min) + min;
    }
private:
    int X;
};

class Random64
{
    typedef unsigned long long uint64;
public:
    typedef uint64 RandomValue;
    Random64& operator = (uint64 seed) { X = seed; return *this; }
    Random64(uint64 seed = 0) :X(seed) {};
    uint64 operator()(uint64 seed = uint64(-1))
    {
        const uint64 a = 3202034522624059733ULL;
        const uint64 c = 1ULL;

        if (seed != uint64(-1)) X = seed;
        uint64 Y = a * X + c;
        X = a * Y + c;
        Y = (Y & 0xFFFFFFFF00000000ULL) | (X >> 32);
        return Y;
    }
    // Не включая max
    uint64 operator()(uint64 min, uint64 max)
    {
        return (*this)() % (max - min) + min;
    }
private:
    uint64 X;
};



int main()
{
    Random64 r(time(0));
    typedef long long int llint;
    int sum = 0;
    llint array_size = r(0, 100000);
    llint* mass_ptr = new llint[array_size];
    for (llint i = 0; i < array_size; i++)
    {
        mass_ptr[i] = r(0, 1000000000);
        cout << "array [" << i << "] = " << mass_ptr[i] << endl;
        if (i == 5)
        {
            sum = sum + mass_ptr[1] + mass_ptr[r(1, 3)];
        }
    }
 
    cout << "Summa ravna = " << sum << endl;
    system("pause");
    return 0;
}

PS我知道现阶段的程序甚至没有实现其本质(据我了解),但这是一种原型 UPD:以及如何缩短该算法?

c++
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Best Answer
    Zealint
    2020-12-18T17:15:40Z2020-12-18T17:15:40Z

    我回答你的问题。

    1问题清楚地表明输入文件input.txt包含输入数据。您的程序应读取此数据并将答案打印到输出文件。你不需要自己生成任何东西。

    例如,输入文件可能如下所示:

    5
    1 2 3 3 4
    

    也就是说,您的程序读取 number 5,然后它必须计算 5 个数字。然后解决问题并将答案输出到文件中output.txt:

    10
    

    当然,这个答案只有在我以与问题的编译器相同的方式理解俄语规范的条件下才是正确的。

    2资源控制必须由您自己完成。制作元素数组100'000在内存方面并没有那么昂贵,你可以自己计算。您完全适合分配的 256 MB。就运行时间而言,您应该尝试在您自己进行的大型测试的计算机上运行您的程序。然后你会知道你是否适合。当您将问题提交给他们时,他们将在他们的自动化测试中运行它(为您的程序替换不同的文件input.txt)并检查它是否在分配的时间内运行并在每个输入文件上产生正确的答案。也就是说,您不需要在程序中对时间和内存进行任何特殊检查。

    • 4
  2. Harry
    2020-12-18T17:13:58Z2020-12-18T17:13:58Z

    应工人的要求:)

    我已经在这里回答了,但我很快就被缺点吐了,所以我决定删除我的答案。但是现在我将返回其中的代码,这是我提出的解决方案之一,不是最佳的,但是......

    int main()
    {
        set<int> a; int n;
        cin >> n;
        for(int x, i = 0; i < n; ++i) { cin >> x; a.insert(x); }
        long long sum = 0;
        for(int x: a) sum = sum + x;
        cout << sum << endl;
    }
    

    第二个代码是一个名为 Mikhailo 的向量。第三个是他自己的代码,但是使用向量ints - 将原始数据存储为 是没有意义的long long,因为它们不超过十亿。好吧,最后一个选项是我的,但set替换为unordered_set. 所以,让我们继续讨论结果。

    我考虑了解决问题的 4 个选项 -

    1. vector<long long>
    2. vector<int>
    3. set<int>
    4. unordered_set<int>

    在实验中,从 100,000 到 10 亿个随机数创建了一个文件,其中至少有 20,000 个是重复的。

    所有 4 个程序均等计算总和。

    我完整记录了时间——从操作系统启动程序到完全退出,结果以毫秒为单位给出了 40 次启动。以 kB 为单位的内存 - 根据 VC ++ 的诊断工具的结果

    5 和 6 - 3 和 4 在评论中添加了 Alexey Nikolaev:

        for(int x, i = 0; i < n; ++i) { 
            cin >> x;  
            if (a.insert(x).second) sum += x; }
    

    全部的:

     Метод         1        2        3        4        5       6
    
     Время     77+-3    77+-7   102+-8    91+-6    98+-5   88+-6
    
    Память       786      395     1567     1966
    

    基本上是你所期望的。使用向量的最快方法。和他在一起,内存消耗最少。

    可能还有其他解决方案,但本质是一样的——数据已经为你准备好了。你的工作就是计算它们。

    • 3
  3. Mikhailo
    2020-12-18T17:28:22Z2020-12-18T17:28:22Z

    只需阅读、删除重复项和总结即可。最主要的是类型long long,以便一切都适合。

    而从内存中——据估计——我们只有一个向量,不超过 100,000 个 8 字节的元素——总共大约 800,000 字节,不到 1 兆字节。

    int main() {
        vector<long long> a;
        size_t n;
        cin >> n;
        a.reserve(n);
        copy_n(istream_iterator<long long>(cin), n, back_inserter(a));
        sort(a.begin(),a.end());
        cout<<accumulate(a.begin(),unique(a.begin(),a.end()),0ll)<<endl;
        }
    
    • 2
  4. Oh-Ben-Ben
    2020-12-19T02:08:50Z2020-12-19T02:08:50Z

    我会张贴我的拐杖)在我看来,等级和矢量是最快的解决方案。

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <iterator>
    #include <random>
    #include <functional>
    #include <vector>
    #include <fstream>
    #include <filesystem>
    #include <numeric>
    
    
    class timeCounter {
    #ifdef __linux__
    public:
        timeCounter() : start(std::chrono::high_resolution_clock().now()),
            end(std::chrono::high_resolution_clock().now()) {};
        ~timeCounter() {
            end = std::chrono::high_resolution_clock().now();
            auto d = end - start;
            std::cout << std::chrono::duration<double, std::ratio_multiply<std::chrono::seconds::period, std::milli>>(d).count() << " ms" << std::endl;
        }
    
    private:
        std::chrono::time_point<std::chrono::_V2::system_clock> start, end;
    #endif // __linux__
    
    #ifdef _WIN32
    public:
        timeCounter() : start(std::chrono::steady_clock::now()) {}
        ~timeCounter() {
            auto end{ std::chrono::steady_clock::now() };
            auto d = end - start;
            std::cout << std::chrono::duration<double, std::ratio_multiply<std::chrono::seconds::period, std::milli>>(d).count() << " ms" << std::endl;
        }
    
    private:
        std::chrono::time_point<std::chrono::steady_clock> start;
    #endif // _WIN32
    
    };
    
    
    std::filesystem::path GetNewCurrentFilePath(std::string file_name) {
        auto path{ std::filesystem::current_path() };
        path = path / file_name;
        if (std::filesystem::exists(path)) {
            std::filesystem::remove(path);
        }
    
        return path;
    }
    
    
    std::filesystem::path GetFilePath(std::string file_name) {
        auto path{ std::filesystem::current_path() };
        path = path / file_name;
        if (!std::filesystem::exists(path)) {
            throw std::runtime_error{ "Error : File not found! : " + path.string() };
        }
    
        return path;
    }
    
    
    void GenData(std::string file_name, std::size_t size, std::size_t low_bord, std::size_t high_bord) {
        timeCounter tc{};
        auto path{ GetNewCurrentFilePath(file_name) };
    
        std::ofstream out_stream(path, std::ios::out);
        if (!out_stream.is_open()) {
            throw std::runtime_error{ "Error open file" };
        }
    
        std::ostream_iterator<uint64_t>{out_stream, "\n"} = size;
    
        std::ostream_iterator<uint64_t> out_it(out_stream, " ");
    
        std::vector<uint64_t> v(size);
        std::mt19937_64 generator(std::random_device{}());
        std::uniform_int_distribution<> uid(low_bord, high_bord);
        auto gen{ std::bind(uid, generator) };
        std::generate(std::begin(v), std::end(v), gen);
    
        std::copy(std::begin(v), std::end(v), out_it);
    
        out_stream.close();
    }
    
    
    uint64_t Processing(std::string file_name) {
        timeCounter tc{};
    
        uint64_t ret{};
    
        auto path{ GetFilePath(file_name) };
    
        std::ifstream in_stream(path, std::ios::in | std::ifstream::binary);
        if (!in_stream.is_open()) {
            throw std::runtime_error{ "Error open file" };
        }
        std::istream_iterator<uint64_t> in_iter{ in_stream };
        std::istream_iterator<uint64_t> in_end{};
    
        uint64_t size{*in_iter };
    
        std::vector<uint64_t> v{};
        v.reserve(size);
    
        std::copy(++in_iter, in_end, std::back_inserter(v));
    
        if (std::is_sorted(std::begin(v), std::end(v))) {
            std::cout << "sorted" << std::endl;
        }
    
        std::cout << "size : " << v.size() << std::endl;
    
        std::sort(std::begin(v), std::end(v));
    
        if (std::is_sorted(std::begin(v), std::end(v))) {
            std::cout << "sorted" << std::endl;
        }
    
        auto last = std::unique(v.begin(), v.end());
        v.erase(last, v.end());
    
        std::cout << "size after erase: " << v.size() << std::endl;
        if (std::is_sorted(std::begin(v), std::end(v))) {
            std::cout << "sorted" << std::endl;
        }
    
        ret = std::accumulate(std::begin(v), std::end(v), 0);
    
        return ret;
    }
    
    
    int main() {
    
        std::string file_name("data");
        std::size_t size{ 100'000 };
        std::size_t low_bor{ 0 };
        std::size_t high_bord{ 1'000'000'000 };
    
        GenData(file_name, size, low_bor, high_bord);
    
        std::cout << Processing(file_name) << std::endl;
    
        return 0;
    }
    
    • 2

相关问题

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5