简体   繁体   English

用cin或scanf输入30万组数字

[英]Input 300 000 sets of numbers with cin or scanf

Hi,你好,

I am participating in programming contest.我正在参加编程比赛。 My algorithm is fine with number of sets to 5000 .我的算法很好,集数为5000 Sets of values are consist of three integers.值集由三个整数组成。 But I enter 300 000 sets of numbers, it takes too long.但是我输入了30万组数字,时间太长了。

Limit of running program: 14s .运行程序限制: 14s Fetching data: 576s .获取数据: 576s (Way too long) (太长了)

My formatted input is:我的格式化输入是:

300000
a b c

300000 - number of sets a, b, c - elements of the set 300000 - 集合的数量 a, b, c - 集合的元素

My algorithm (dont judge about the code):我的算法(不要判断代码):

#include <iostream>

using namespace std;
int min_replacements(int n, int *ds, int *ps, int *rs);
int max(int a, int b, int c);
bool ot(int a, int b, int c);
bool ooo(int a, int b, int c);
bool to(int a, int b, int c);
int main()
{
    int n = 0;
    cin >> n;
    int *ds, *ps, *rs;
    ds = new int[n];
    ps = new int[n];
    rs = new int[n];
    int d{}, p{}, r{};
    for (int i = 0; i < n; i++)
    {
        scanf("%d %d %d", &ds[i], &ps[i], &rs[i]);
        printf("%d", i);
    }
    int t = min_replacements(n, ds, ps, rs);
    printf("%d\n", t);
    delete[] ds;
    delete[] ps;
    delete[] rs;
}
bool ot(int a, int b, int c)
{
    return (a != 0 && b == 0 && c == 0);
}
bool ooo(int a, int b, int c)
{
    return (a == 0 && b != 0 && c == 0);
}
bool to(int a, int b, int c)
{
    return (a == 0 && b == 0 && c != 0);
}
int max(int a, int b, int c)
{
    int m = 0;
    if (a == b && c < a)
    {
        m = a;
    }
    if (b == c && a < b)
    {
        m = b;
    }
    if (a == c && b < c)
    {
        m = c;
    }
    if (b < a && c < a)
    {
        m = a;
    }
    if (a < b && c < b)
    {
        m = b;
    }
    if (a < c && b < c)
    {
        m = c;
    }
    if (a == b && b == c)
    {
        m = a;
    }
    return m;
}
int min_replacements(int n, int *ds, int *ps, int *rs)
{
    int t = 0;
    if (ds[0] == ps[0] && ps[0] == rs[0] && ds[0] == rs[0])
    {
        return (n + ps[0]) * rs[0];
    }
    bool loop = true;
    while (loop)
    {
        for (int i = 0; i < n - 1; ++i)
        {
            if (ot(*(ds + i), *(ps + i), *(rs + i)) || ooo(*(ds + i), *(ps + i), *(rs + i)) || to(*(ds + i), *(ps + i), *(rs + i)))
            {
                continue;
            }
            int m = max(*(ds + i), *(ps + i), *(rs + i));
            if (m == *(ds + i))
            {
                *(ps + i + 1) += *(ps + i);
                *(rs + i + 1) += *(rs + i);
                *(ps + i) = *(rs + i) = 0;
                t += 2;
            }
            if (m == *(ps + i))
            {
                *(ds + i + 1) += *(ds + i);
                *(rs + i + 1) += *(rs + i);
                *(ds + i) = *(rs + i) = 0;
                t += 2;
            }
            if (m == *(rs + i))
            {
                *(ds + i + 1) += *(ds + i);
                *(ps + i + 1) += *(ps + i);
                *(ps + i) = *(ds + i) = 0;
                t += 2;
            }
        }
        for (int i = 0; i < n; ++i)
        {
            if (ot(*(ds + i), *(ps + i), *(rs + i)) || ooo(*(ds + i), *(ps + i), *(rs + i)) || to(*(ds + i), *(ps + i), *(rs + i)))
            {
                loop = false;
            }
            else
            {
                loop = true;
            }
        }
        if (loop)
        {
            *ds += *(ds + n - 1);
            *ps += *(ps + n - 1);
            *rs += *(rs + n - 1);
            *(ds + n - 1) = *(ps + n - 1) = *(rs + n - 1) = 0;
            t -= 2;
        }
    }
    if (t == 0)
        return 0;
    return t + 1;
}

I used a cin in this algorithm Can you help me?我在这个算法中使用了 cin 你能帮我吗? Thank you so much.非常感谢。

How do you know the std::cin part is the problem?你怎么知道std::cin部分是问题所在? Did you profile your code?你有没有分析你的代码? If not, I suggest doing that, it's often surprising which part of the code is taking up most time.如果没有,我建议这样做,通常令人惊讶的是代码的哪一部分占用了最多的时间。 See eg How can I profile C++ code running on Linux?参见例如如何分析在 Linux 上运行的 C++ 代码? . .

You're doing a lot of unnecessary work in various parts of the code.您在代码的各个部分做了很多不必要的工作。 For example, your max function does at least 7 comparissons, and looks extremely error prone to write.例如,您的 max 函数至少进行了 7 次比较,并且看起来非常容易出错。 You could simply replace the whole function by:您可以简单地将整个函数替换为:

std::max({ a, b, c })

I would also take a look at your min_replacements function and see if it can be simplified.我也会看看你的min_replacements函数,看看它是否可以简化。 Unfortunately, you're using variable names which are super vague, so it's pretty much impossible to understand what the code should be doing.不幸的是,您使用的变量名非常模糊,因此几乎不可能理解代码应该做什么。 I suggest using much more descriptive variable names.我建议使用更具描述性的变量名称。 That way the code will become much easier to reason about.这样,代码将变得更容易推理。 The way it's currently written, there's a very good change even you yourself won't be able to make sense of it in a month's time.它目前的编写方式,有一个非常好的变化,即使你自己在一个月内也无法理解它。

Just glacing over the min_replacements function though, there's definitely a lot more work going on than necessary.不过,只要浏览一下min_replacements函数,肯定有很多不必要的工作要做。 Eg the last for-loop:例如最后一个 for 循环:

   for (int i = 0; i < n; ++i)
    {
        if (ot(*(ds + i), *(ps + i), *(rs + i)) || ooo(*(ds + i), *(ps + i), *(rs + i)) || to(*(ds + i), *(ps + i), *(rs + i)))
        {
            loop = false;
        }
        else
        {
            loop = true;
        }
    }

Each loop iterator sets the loop variable.每个循环迭代器设置loop变量。 Assuming this code is correct, you don't need the loop at all, just do the check only once for i = n - 1 .假设此代码是正确的,您根本不需要循环,只需对i = n - 1一次检查。 That's already O(n) changed to O(1) .那已经O(n)更改为O(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM