0
\$\begingroup\$

So, I've recently started working on CodeForces to practice from older contests (and maybe even start participating in current ones), but there is one problem that I can't seem to make an efficient enough program to pass all tests. Here is my code:

#include <bits/stdc++.h>
using namespace std;
struct food
{
    long long stock, cost;
} v[100005];
struct sorted_food
{
    long long type, cost;
} s[100005];
bool compare (sorted_food lhs, sorted_food rhs)
{
    return (lhs.cost < rhs.cost && lhs.cost && rhs.cost);
}
int main()
{
    struct order
    {
        long type;
        long long dishes;
    } cust; ///cust = customer
    struct minim
    {
        long pos=0;
        long value=2147483647;
    } mn;
    long long i,n,m,cost,d,j,k=1;
    cin >> n >> m;
    for (i=1; i<=n; i++)
    {
        cin >> v[i].stock;
    }
    for (i=1; i<=n; i++)
    {
        cin >> v[i].cost;
        s[k].cost = v[i].cost;
        s[k].type = i;
        k++;
        if (v[i].cost < mn.value && v[i].stock)
        {
            mn.value = v[i].cost;
            mn.pos = i;
        }
    }
    sort(s + 1, s + k, compare);
    for (i=1; i<=m; i++)
    {
        cost = 0;
        cin >> cust.type >> cust.dishes;
        d=v[cust.type].stock;
        v[cust.type].stock -= cust.dishes;
        if (v[cust.type].stock >= 0)
            cost = v[cust.type].cost * cust.dishes;
        else
        {
            cost = v[cust.type].cost * (cust.dishes + v[cust.type].stock);
            v[cust.type].stock = 0;
            cust.dishes -= d;
            while (cust.dishes)
            {
                if (cust.dishes > v[mn.pos].stock)
                {
                    cust.dishes = cust.dishes - v[mn.pos].stock;
                    cost += v[mn.pos].stock * v[mn.pos].cost;
                    v[mn.pos].stock = 0;
                    mn.value = 2147483647;
                    mn.pos = 0;
                    for (j=1; j<=k; j++)
                    {
                        if (v[s[j].type].cost <= mn.value && v[s[j].type].stock)
                        {
                            mn.value = v[s[j].type].cost;
                            mn.pos = s[j].type;
                            break;
                        }
                    }
                    if (mn.value == 2147483647 && cust.dishes)
                    {
                        cost = 0;
                        cust.dishes = 0;
                    }
                }
                else
                {
                    cost += v[mn.pos].cost * cust.dishes;
                    v[mn.pos].stock -= cust.dishes;
                    cust.dishes = 0;
                }
            }
        }
        cout << cost << "\n";
    }
}

I know I haven't written my code to look its best, but it'll do, I suppose.

B. Lunar New Year And Food Ordering

The restaurant "Alice's" serves \$n\$ kinds of food. The cost for the \$i\$-th kind is always \$c_i\$. Initially, the restaurant has enough ingredients for serving exactly \$a_i\$ dishes of the \$i\$-th kind. In the New Year's Eve, \$m\$ customers will visit Alice's one after another and the \$j\$-th customer will order \$d_j\$ dishes of the \$t_j\$-th kind of food. The \$(i+1)\$-st customer will only come after the i-th customer is completely served.

Suppose there are \$r_i\$ dishes of the \$i\$-th kind remaining (initially \$r_i = a_i\$). When a customer orders \$1\$ dish of the \$i\$-th kind, the following principles will be processed.

  1. If \$r_i > 0\$, the customer will be served exactly \$1\$ dish of the \$i\$-th kind. The cost for the dish is \$c_i\$. Meanwhile, \$r_i\$ will be reduced by \$1\$.
  2. Otherwise, the customer will be served \$1\$ dish of the cheapest available kind of food if there are any. If there are multiple cheapest kinds of food, the one with the smallest index among the cheapest will be served. The cost will be the cost for the dish served and the remain for the corresponding dish will be reduced by \$1\$.
  3. If there are no more dishes at all, the customer will leave angrily. Therefore, no matter how many dishes are served previously, the cost for the customer is \$0\$.

If the customer doesn't leave after the \$d_j\$ dishes are served, the cost for the customer will be the sum of the cost for these \$d_j\$ dishes.

Please determine the total cost for each of the \$m\$ customers.

Input

The first line contains two integers \$n\$ and \$m\$ (\$ 1 ≤ n, m ≤ 10^5\$), representing the number of different kinds of food and the number of customers, respectively.

The second line contains \$n\$ positive integers \$a_1, a_2,\ldots, a_n\$ (\$1 ≤ a_i ≤ 10^7\$), where \$a_i\$ denotes the initial remain of the \$i\$-th kind of dishes.

The third line contains \$n\$ positive integers \$c_1, c_2, \ldots, c_n\$ (\$1 ≤ c_i ≤ 10^6\$), where \$c_i\$ denotes the cost of one dish of the \$i\$-th kind.

The following \$m\$ lines describe the orders of the \$m\$ customers respectively. The \$j\$-th line contains two positive integers \$t_j\$ and \$d_j\$ (\$1 ≤ t_j ≤ n\$, \$1 ≤ d_j ≤ 10^7\$), representing the kind of food and the number of dishes the \$j\$-th customer orders, respectively.

Output

Print \$m\$ lines. In the \$j\$-th line print the cost for the \$j\$-th customer.

Requirements

  • time limit per test: 2 seconds
  • memory limit per test: 256 megabytes
  • input: standard input
  • output: standard output

From the time the evaluator is spending to evaluate the time-limit-exceeded test, I'm thinking my program gets stuck somewhere. Hoping to get some advice from you guys!

Edit: definitely the code gets stuck somewhere, I just replaced my old and inefficient search for a sorted array and the results are the same.

\$\endgroup\$
5
  • \$\begingroup\$ Unfortunately, "definitely the code gets stuck somewhere" sounds like this is actually off-topic here. \$\endgroup\$ Commented Feb 6, 2019 at 16:18
  • \$\begingroup\$ @JerryCoffin If this is off-topic here, then it is off-topic everywhere on Stack, as other categories don't seem to be very helpful when talking about checking code. And, by checking code, I think I have already made my code eligible to Code Review. Off-topic shouldn't mean you can't give me ideas, but on Stack this is what it means, apparently. \$\endgroup\$
    – antoniu200
    Commented Feb 6, 2019 at 17:30
  • 2
    \$\begingroup\$ Although I agree that it's kind of a pain, the basic idea is apparently that you should post a question to SO to help with getting it to actually work correctly (not necessarily fast enough to complete all the tests in time, but dependably does the job--eventually). Then when it's all working, you can post it here to get help with improving style, making it faster, and so on. \$\endgroup\$ Commented Feb 6, 2019 at 17:33
  • \$\begingroup\$ @JerryCoffin Time-limit exceeded questions are not necessarily off-topic \$\endgroup\$
    – Mast
    Commented Feb 7, 2019 at 6:22
  • \$\begingroup\$ @Mast: Yes, but at least as I read things, he's saying there's actually a bug, not just too slow of execution. \$\endgroup\$ Commented Feb 7, 2019 at 6:57

1 Answer 1

3
\$\begingroup\$

You have a couple of compiler warnings:

24: error: ISO C++ forbids initialization of member ‘pos’
24: error: making ‘pos’ static
24: error: ISO C++ forbids in-class initialization of non-const static member ‘pos’
24: error: local class ‘struct main()::minim’ shall not have static data member ‘long int main()::minim::pos’
25: error: ISO C++ forbids initialization of member ‘value’
25: error: making ‘value’ static
25: error: ISO C++ forbids in-class initialization of non-const static member ‘value’
25: error: local class ‘struct main()::minim’ shall not have static data member ‘long int main()::minim::value’

Not a valid header:

#include <bits/stdc++.h>

This declaration is bad practice: See: https://stackoverflow.com/q/1452721/14065 second answer is the best.

using namespace std;

One declaration per line please.

    long long stock, cost;

You are making copies of the parameter here.

bool compare (sorted_food lhs, sorted_food rhs)

Pass by const reference to avoid a copy.
If you had written your types above properly you have spotted that it was more expensive to copy than passing a reference.

This looks completely garbage:

    return (lhs.cost < rhs.cost && lhs.cost && rhs.cost);

Let's have a Look:

    A Cost  B Cost    A < B    B < A
       5      6         T        F           OK
       5      0         F        F           Hmmmm So they are equal?
       0      6         F        F           Hmmmm
       0      0         F        F           Hmmmm 

What on earth!!!

    long long i,n,m,cost,d,j,k=1;

One variable per line. Only declare variables at the point you need them. This is not C89. You don't need to declare all the variables at the top. It gives you no speed benefit to declare them all at the top. It gives you no speed benefit to declare variables that are only 1 character lone give them a name so we can read the code.

If you can read the code you have a better chance of spotting better algorithms.

This is a bit eccentric way of writing a loop!

    for (i=1; i<=m; i++)

    // Normally written like this:
    for (int i=0; i < m; ++i)

Yep, as expected the rest is unreadable so I can't suggest a better algorithm.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.