1760 - Optim: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: Gigel primea de la mama lui, ca temă, o foaie pe care era scris un şir de N numere întregi. Singurul calcul pe care ştia să îl facă până acum era suma tuturor numerelor. Pentru aceasta el plasa N-1 semne de adunare, +, între numerele aflate pe poziţii consecutive în şir şi calcula astfel suma acestor numere. Între timp a crescut şi a învăţat şi operaţia de înmulţire pentru care foloseşte semnul *. Din şirul celor N-1 semne de adunare, îi trece prin m...
 
No edit summary
 
Line 1: Line 1:
Gigel primea de la mama lui, ca temă, o foaie pe care era scris un şir de N numere întregi. Singurul calcul pe care ştia să îl facă până acum era suma tuturor numerelor. Pentru aceasta el plasa N-1 semne de adunare, +, între numerele aflate pe poziţii consecutive în şir şi calcula astfel suma acestor numere. Între timp a crescut şi a învăţat şi operaţia de înmulţire pentru care foloseşte semnul *. Din şirul celor N-1 semne de adunare, îi trece prin minte să înlocuiască K semne + cu K semne *.
Gigel primea de la mama lui, ca temă, o foaie pe care era scris un şir de <code>N</code> numere întregi. Singurul calcul pe care ştia să îl facă până acum era suma tuturor numerelor. Pentru aceasta el plasa <code>N-1</code> semne de adunare, +, între numerele aflate pe poziţii consecutive în şir şi calcula astfel suma acestor numere. Între timp a crescut şi a învăţat şi operaţia de înmulţire pentru care foloseşte semnul *. Din şirul celor <code>N-1</code> semne de adunare, îi trece prin minte să înlocuiască <code>K</code> semne + cu <code>K</code> semne *.
<br>
 
Îşi dă seama că tema se complică, deoarece înmulţirile trebuie efectuate înaintea adunărilor, dar nu se dă bătut şi duce calculul până la capăt.
Îşi dă seama că tema se complică, deoarece înmulţirile trebuie efectuate înaintea adunărilor, dar nu se dă bătut şi duce calculul până la capăt.
== Cerința ==
 
= Cerința =
Scrieţi un program care să determine valoarea minimă pe care o poate obţine şi valoarea maximă pe care o poate obţine după înlocuirea menţionată.
Scrieţi un program care să determine valoarea minimă pe care o poate obţine şi valoarea maximă pe care o poate obţine după înlocuirea menţionată.
== Date de intrare ==
Fişierul de intrare optimin.txt conţine pe prima linie numerele naturale N şi K, separate printr-un spaţiu, reprezentând numărul de numere întregi din şir, respectiv numărul de operaţii de înmulţire ce vor fi efectuate. Pe cea de a doua linie se află N numere întregi separate prin câte un spaţiu, x1,x2,…xN
, reprezentând numerele din şir.
== Date de ieșire ==
Fişierul de ieşire optimout.txt va conţine pe o singură linie, separate printr-un spaţiu, în ordine crescătoare, cele două valori cerute.
== Restricții și precizări ==
*'''2 ≤ N ≤ 30'''
*'''0 ≤ K ≤ 9; K < N'''
*'''-8 ≤ xi ≤ 8,  1 ≤ i ≤ N'''
== Exemplul 1 ==
; optimin.txt
: 6 3
: 2
: 0
: 3
: -1
: 7
: -4
; optimout.txt
: -31 86
<br>
== Exemplul 2 ==
; optimin.txt
: 8 2
: -3
: 5
: 2
: 4
: -1
: 0
: -2
: 7
; optimout.txt
: -54 840
<br>
== Rezolvare ==
<syntaxhighlight lang="python" line>
#1760 - Optim
def calc_min_max_values(N, K, numbers):
    # Verificăm restricțiile
    if not (2 <= N <= 30) or not (0 <= K < N):
        return "Fals"


    # Inițializăm valorile minime și maxime cu suma inițială
= Date de intrare =
    min_value = sum(numbers)
Fişierul de intrare <code>optimIN.txt</code> conţine pe prima linie numerele naturale <code>N</code> şi <code>K</code>, separate printr-un spaţiu, reprezentând numărul de numere întregi din şir, respectiv numărul de operaţii de înmulţire ce vor fi efectuate. Pe cea de a doua linie se află <code>N</code> numere întregi separate prin câte un spaţiu, , reprezentând numerele din şir.
    max_value = sum(numbers)


    # Generăm toate combinațiile de poziții pentru înmulțire
= Date de ieșire =
    for i in range(1 << (N - 1)):
Fişierul de ieşire <code>optimOUT.txt</code> va conţine pe o singură linie, separate printr-un spaţiu, în ordine crescătoare, cele două valori cerute. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
        # Convertim i la binar și adăugăm zerouri la început pentru a obține o reprezentare cu N-1 cifre binare
        binary_repr = bin(i)[2:].zfill(N - 1)


        # Calculăm suma pentru configurația curentă
= Restricții și precizări =
        current_sum = numbers[0]
        current_multiply_count = 0


        for j in range(N - 1):
* <code>2 ≤ N ≤ 30</code>
            if binary_repr[j] == '0':
* <code>0 ≤ K ≤ 9; K < N</code>
                current_sum += numbers[j + 1]
* <code>-8 ≤ xi</code> <code>≤ 8,  1 ≤ i ≤ N</code>
            else:
                current_sum *= numbers[j + 1]
                current_multiply_count += 1


        # Actualizăm valorile minime și maxime
= Exemplu 1: =
        min_value = min(min_value, current_sum)
<code>optimIN.txt</code>
        max_value = max(max_value, current_sum)
6 3
2
0
3
-1
7
-4
<code>optimOUt.txt</code>
-31 86


        # Verificăm dacă numărul de înmulțiri este cel dorit (K)
=== Explicație ===
        if current_multiply_count == K:
<code>2 * 0 + 3 * (-1)  + 7 * (-4) = -31</code>
            break


    return min_value, max_value
<code>2 + 0 + 3 * (-1)  * 7 * (-4)  = 86</code>.


# Citim datele de intrare din fișierul "optimin.txt"
= Exemplu 2: =
with open("optimin.txt", "r") as file:
<code>optimIN.txt</code>
    N, K = map(int, file.readline().split())
6 8
    numbers = list(map(int, file.readline().split()))
2
0
3
-1
7
-4
<code>optimOUt.txt</code>
Datele nu corespund restrictiilor impuse


# Calculăm valorile minime și maxime
== Rezolvare ==
result = calc_min_max_values(N, K, numbers)
<syntaxhighlight lang="python" line="1">
def verificare_restrictii(N, K, A):
    if not (2 <= N <= 30) or not (0 <= K <= 9) or not (K < N):
        return False
    if not all(-8 <= x <= 8 for x in A):
        return False
    return True


# Scriem rezultatele în fișierul "optimout.txt" sau afișăm "Fals" în cazul în care restricțiile nu sunt respectate
def back(lv, k, aux, suma, A, N):
with open("optimout.txt", "w") as file:
    global maxim, minim
     if isinstance(result, tuple):
    if lv == N:
         file.write(f"{result[0]} {result[1]}")
        suma += aux
     else:
        if suma > maxim:
         file.write(result)
            maxim = suma
        if suma < minim:
            minim = suma
        return
     if N - lv > k:
         back(lv + 1, k, A[lv], suma + aux, A, N)
     if k > 0:
         back(lv + 1, k - 1, aux * A[lv], suma, A, N)


</syntaxhighlight>
def main():
    global maxim, minim
   
    with open("optimIN.txt", "r") as fin:
        N, K = map(int, fin.readline().strip().split())
        A = [int(fin.readline().strip()) for _ in range(N)]
   
    if not verificare_restrictii(N, K, A):
        with open("optimOUT.txt", "w") as fout:
            fout.write("Datele nu corespund restrictiilor impuse\n")
        return
   
    maxim = -2000000000
    minim = 2000000000
   
    back(1, K, A[0], 0, A, N)
   
    with open("optimOUT.txt", "w") as fout:
        fout.write(f"{minim} {maxim}\n")


== Explicatie ==
if __name__ == "__main__":
2 * 0 + 3 * (-1) + 7 * (-4)  = -31
    main()


2 + 0 + 3 * (-1)  * 7 * (-4)  = 86.
</syntaxhighlight>

Latest revision as of 12:31, 18 May 2024

Gigel primea de la mama lui, ca temă, o foaie pe care era scris un şir de N numere întregi. Singurul calcul pe care ştia să îl facă până acum era suma tuturor numerelor. Pentru aceasta el plasa N-1 semne de adunare, +, între numerele aflate pe poziţii consecutive în şir şi calcula astfel suma acestor numere. Între timp a crescut şi a învăţat şi operaţia de înmulţire pentru care foloseşte semnul *. Din şirul celor N-1 semne de adunare, îi trece prin minte să înlocuiască K semne + cu K semne *.

Îşi dă seama că tema se complică, deoarece înmulţirile trebuie efectuate înaintea adunărilor, dar nu se dă bătut şi duce calculul până la capăt.

Cerința[edit | edit source]

Scrieţi un program care să determine valoarea minimă pe care o poate obţine şi valoarea maximă pe care o poate obţine după înlocuirea menţionată.

Date de intrare[edit | edit source]

Fişierul de intrare optimIN.txt conţine pe prima linie numerele naturale N şi K, separate printr-un spaţiu, reprezentând numărul de numere întregi din şir, respectiv numărul de operaţii de înmulţire ce vor fi efectuate. Pe cea de a doua linie se află N numere întregi separate prin câte un spaţiu, , reprezentând numerele din şir.

Date de ieșire[edit | edit source]

Fişierul de ieşire optimOUT.txt va conţine pe o singură linie, separate printr-un spaţiu, în ordine crescătoare, cele două valori cerute. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări[edit | edit source]

  • 2 ≤ N ≤ 30
  • 0 ≤ K ≤ 9; K < N
  • -8 ≤ xi ≤ 8, 1 ≤ i ≤ N

Exemplu 1:[edit | edit source]

optimIN.txt

6 3
2
0
3
-1
7
-4

optimOUt.txt

-31 86

Explicație[edit | edit source]

2 * 0 + 3 * (-1) + 7 * (-4) = -31

2 + 0 + 3 * (-1) * 7 * (-4) = 86.

Exemplu 2:[edit | edit source]

optimIN.txt

6 8
2
0
3
-1
7
-4

optimOUt.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1"> def verificare_restrictii(N, K, A):

   if not (2 <= N <= 30) or not (0 <= K <= 9) or not (K < N):
       return False
   if not all(-8 <= x <= 8 for x in A):
       return False
   return True

def back(lv, k, aux, suma, A, N):

   global maxim, minim
   if lv == N:
       suma += aux
       if suma > maxim:
           maxim = suma
       if suma < minim:
           minim = suma
       return
   if N - lv > k:
       back(lv + 1, k, A[lv], suma + aux, A, N)
   if k > 0:
       back(lv + 1, k - 1, aux * A[lv], suma, A, N)

def main():

   global maxim, minim
   
   with open("optimIN.txt", "r") as fin:
       N, K = map(int, fin.readline().strip().split())
       A = [int(fin.readline().strip()) for _ in range(N)]
   
   if not verificare_restrictii(N, K, A):
       with open("optimOUT.txt", "w") as fout:
           fout.write("Datele nu corespund restrictiilor impuse\n")
       return
   
   maxim = -2000000000
   minim = 2000000000
   
   back(1, K, A[0], 0, A, N)
   
   with open("optimOUT.txt", "w") as fout:
       fout.write(f"{minim} {maxim}\n")

if __name__ == "__main__":

   main()

</syntaxhighlight>