2010 - Fermier

De la Universitas MediaWiki
Versiunea din 26 iulie 2024 06:14, autor: RaulOtet (discuție | contribuții) (Pagină nouă: Dorel și-a achiziționat o fermă cu <code>n</code> plantații și o mașină de transport cu o capacitate <code>c</code>, pentru transportul de îngrășăminte la toate plantațiile. Îngrășămintele se află într-un depozit, în cantitate suficientă pentru scopul propus. Plantațiile și depozitul sunt dispuse sub forma unui cerc. Există drumuri doar între plantația <code>i</code> și plantația <code>i+1</code> (<code>1≤i≤n-1</code>), precum și între depozit...)
(dif) ← Versiunea anterioară | Versiunea curentă (dif) | Versiunea următoare → (dif)

Dorel și-a achiziționat o fermă cu n plantații și o mașină de transport cu o capacitate c, pentru transportul de îngrășăminte la toate plantațiile. Îngrășămintele se află într-un depozit, în cantitate suficientă pentru scopul propus. Plantațiile și depozitul sunt dispuse sub forma unui cerc. Există drumuri doar între plantația i și plantația i+1 (1≤i≤n-1), precum și între depozit și plantația 1 și depozit și plantația n, ca în figură.

La o plantație i se poate ajunge de la depozit trecând prin plantațiile 1, 2,…, i-1 sau prin plantațiile n, n-1, …, i+1, alegerea făcându-se în funcție de traseul cel mai scurt. Se cunosc aceste distanțe, precum și cantitatea de îngrășăminte necesară pentru fiecare plantație. La fiecare încărcare, Dorel ia din depozit exact cantitatea c. Dorel vrea să-și organizeze bine munca la fermă și să consume cât mai puțină benzină prin alegerea celor mai scurte trasee de parcurs. Plantațiile trebuie să fie aprovizionate obligatoriu în ordinea următoare: mai întâi plantația 1, apoi plantația 2, plantația 3,…, plantația n. În plus, și-a propus să încarce o nouă cantitate de îngrășământ doar după ce a folosit toată cantitatea încărcată anterior. Transportarea îngrășămintelor pe plantații se face deci, începând cu plantația 1. După ce se transportă toată cantitatea necesară pentru această plantație, se trece la plantația 2, și tot așa în ordine la 3, 4 etc. până se deservește ultima plantație. Dacă după ce s-au transportat îngrășămintele necesare pentru plantația i în mașină au mai rămas încă îngrășăminte, acestea trebuie utilizate în continuare pentru alte plantații, alese în ordinea impusă (începând cu plantația i+1, apoi i+2 etc.), până se epuizează toată cantitatea transportată de mașină. Astfel, dacă de la plantația i trebuie să ajungă la plantația i+1, va alege cel mai scurt traseu dintre traseul direct de la plantația i la i+1 și traseul care trece prin plantațiile i-1, i-2, …, 1, depozit, n, n-1, …, i+1. La final, mașina trebuie să se întoarcă la depozit, goală sau cu cantitatea rămasă după aprovizionarea cu îngrășăminte a plantației n.

Cerința

Ajutați-l pe Dorel să calculeze distanța parcursă pentru a transporta îngrășăminte la toate cele n plantații, conform cerințelor.

Date de intrare

Fișierul de intrare fermier.in conține pe prima linie numerele naturale n și c, separate printr-un spațiu. A doua linie conține numerele naturale d[0], d[1], d[2], …, d[n-1], d[n] separate două câte două prin câte un spaţiu, unde d[0] este distanța dintre prima plantație și depozit, d[i] (1≤i≤n-1) este distanța între plantația i și plantația i+1, iar d[n] este distanța dintre plantația n și depozit. Pe linia a treia se găsesc numerele naturale q[1], q[2],…, q[n-1], q[n] separate două câte două prin câte un spaţiu, q[i] reprezentând cantitatea de îngrășăminte necesară pentru plantația i (1≤i≤n).

Date de ieșire

Fișierul de ieșire fermier.out va conține pe prima linie un număr natural conform cerinţei.

Restricții și precizări

  • 1 ≤ n ≤ 100
  • 1 ≤ n ≤ 2, pentru teste în valoare de 20 de puncte;
  • 1 ≤ d[i] ≤ 1000, 1 ≤ i ≤ n;
  • 1 ≤ q[i] ≤ 1000, 1 ≤ i ≤ n;
  • 1 ≤ c ≤ 1000;
  • În concurs s-au acordat 10 puncte din oficiu. Pe site se acordă 10 puncte pentru exemplu.

Exemplu:

fermier.in

3 6
1 10 2 3
13 2 7

fermier.out

22

Explicație

La plantația 1 trebuie transportată o cantitate egală cu 13, valoarea maximă pe care o poate transporta mașina fiind de 6. La plantația 1 se ajunge pe drumul cel mai scurt direct de la depozit. Astfel se va merge mai întâi cu cantitatea 6, ne întoarcem la depozit, încărcam iar mașina, ducem 6, ne întoarcem, încărcăm și lăsăm doar 1 (atât mai este necesar). Pentru aceasta, s-a parcurs distanța de 1+1+1+1+1=5. În mașină a mai rămas acum o cantitate egală cu 5. Trebuie să mergem acum la plantația 2 pe drumul cel mai scurt. Pe drumul direct distanța este 10, iar pe drumul invers care trece iar prin depozit este 6 (1+3+2). Vom alege drumul cu distanța 6. Lăsăm cantitatea 2 (atât e necesar plantației 2), ne mai rămân 3 și pentru plantația 3. De la plantația 2 se ajunge direct la plantația 3 pe o distanță egală cu 2 sau invers, trecând prin depozit pe o distanță de 14 (10+1+3). Alegem drumul cu distanța 2. Lăsăm îngrășămintele rămase și mai mergem iar la depozit, încărcăm și lăsăm 4 la plantația 3. Pentru aceasta mai parcurgem distanța 3+3. La final mașina trebuie să se întoarcă la depozit, deci încă un drum cu distanța 3. În total: 5+6+2+6+3=22.

def shortest_distance(depot_to_1, depot_to_n, distances, c, requirements):
    n = len(requirements)
    total_distance = 0
    current_fertilizer = 0

    # Helper function to calculate shortest path between two plantations
    def calculate_shortest_path(i, j):
        if i < j:
            direct_path = sum(distances[i:j])
        else:
            direct_path = sum(distances[j:i])
        through_depot = depot_to_1 + depot_to_n
        return min(direct_path, through_depot)

    # Start from depot to the first plantation
    total_distance += depot_to_1
    current_index = 0

    while current_index < n:
        # If not enough fertilizer, go back to depot
        if current_fertilizer < requirements[current_index]:
            total_distance += depot_to_1  # Return to depot
            current_fertilizer = c
            total_distance += depot_to_1  # Go back to the current plantation

        # Fulfill the current plantation's requirement
        while current_index < n and current_fertilizer >= requirements[current_index]:
            current_fertilizer -= requirements[current_index]
            current_index += 1
            if current_index < n:
                total_distance += calculate_shortest_path(current_index - 1, current_index)

    # Return to depot after the last plantation
    total_distance += depot_to_1

    return total_distance

# Example of usage:
depot_to_1 = 10
depot_to_n = 15
distances = [5, 8, 10, 12, 6]  # Distances between consecutive plantations
c = 20  # Capacity of the truck
requirements = [5, 10, 8, 12, 6]  # Fertilizer requirements for each plantation

result = shortest_distance(depot_to_1, depot_to_n, distances, c, requirements)
print(result)