2676 - Afise: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: == Cerința == Fiind date lungimea zidului, câte unităţi sunt deteriorate, care este numărul maxim de panouri ce pot fi folosite şi care sunt unităţile de zid deteriorate, se cere să se determine lungimea minimă totală a panourilor care sunt folosite pentru a acoperi zona şi câte panouri se folosesc. Lungimea minimă o definim ca numărul total de unităţi de zid acoperite astfel încât să fie mascate zonele problemă. Pentru acoperirea unităţilor de zid dete...
 
No edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
== Cerința ==
Campania electorală s-a terminat de mult, dar zidul din parcul central al oraşului în care au fost puse afişele este încă într-o formă dezolantă. Ploile şi vântul au acţionat şi au urâţit şi mai mult această zonă pe care altă dată erau afişe frumos colorate. Primăria a decis să se ocupe de această problemă. A format o comisie şi a decis realizarea unor panouri reclamă care să ascundă porţiunile deteriorate. Deoarece fondurile sunt mici s-a decis să fie alocate doar un anumit număr de panouri publicitare care trebuie să ocupe o suprafaţă cât mai mică posibil. Comisia a primit datele din teren sub forma: lungime zid, câte unităţi sunt ocupate cu afişe ce trebuie acoperite şi care este numărul de panouri pe care le poate folosi. De asemenea se primesc ca date şi care sunt unităţile de zid ocupate cu afişe deja deteriorate.
 
= Cerința =
Fiind date lungimea zidului, câte unităţi sunt deteriorate, care este numărul maxim de panouri ce pot fi folosite şi care sunt unităţile de zid deteriorate, se cere să se determine lungimea minimă totală a panourilor care sunt folosite pentru a acoperi zona şi câte panouri se folosesc. Lungimea minimă o definim ca numărul total de unităţi de zid acoperite astfel încât să fie mascate zonele problemă. Pentru acoperirea unităţilor de zid deteriorate, nu este neapărat necesar să se folosească toate panourile. Numărul de panouri folosite fiind limitat există posibilitatea să fie acoperite şi zone din zid care sunt curate.
Fiind date lungimea zidului, câte unităţi sunt deteriorate, care este numărul maxim de panouri ce pot fi folosite şi care sunt unităţile de zid deteriorate, se cere să se determine lungimea minimă totală a panourilor care sunt folosite pentru a acoperi zona şi câte panouri se folosesc. Lungimea minimă o definim ca numărul total de unităţi de zid acoperite astfel încât să fie mascate zonele problemă. Pentru acoperirea unităţilor de zid deteriorate, nu este neapărat necesar să se folosească toate panourile. Numărul de panouri folosite fiind limitat există posibilitatea să fie acoperite şi zone din zid care sunt curate.
== Date de intrare ==
Fișierul de intrare afise.in conţine pe prima linie trei valori separate prin câte un spaţiu L n k, cu semnificația: L lungimea totală a zidului, n numărul de unităţi ce urmează a fi acoperite şi k numărul maxim de panouri ce pot fi folosite. Pe a doua linie separate prin câte un spațiu sunt n valori x1, x2, … , xn, unde xi reprezintă unitatea din zid care este acoperită de un afiș vechi. Valorile x1, x2, … , xn apar într-o ordine aleatoare.
== Date de ieșire ==
Fișierul de ieșire afise.out va conține o singură linie cu două valori val Nk, ce reprezintă lungimea minimă totală folosită și numărul de panouri folosite astfel încât toate zonele deteriorate să fie acoperite.
== Restricții și precizări ==
~ 0 < L ≤ 1000
<br>
~ 0 < n ≤ L
<br>
~ 0 < k ≤ L / 2
== Exemplu 1 ==
; Intrare
: afise.in
:25 8 3
:3 11 6 4 19 15 20 12
; Ieșire
: afise.out
:11 3
<br>
== Exemplu 2 ==
; Intrare
: afise.in
:10 4 6
:7 3 8 1
; Ieșire
: afise.out
:4 3
<br>
== Rezolvare ==
<syntaxhighlight lang="python" line>
#2676 - Afise
def acoperire_zid(L, n, k, unitati_deteriorate):
    unitati_deteriorate.sort()
    lungime_minima = 0
    panouri_folosite = 0


    if k >= n:
= Date de intrare =
        lungime_minima = L
Fișierul de intrare <code>afiseIN.txt</code> conţine pe prima linie trei valori separate prin câte un spaţiu <code>L n k</code>, cu semnificația: <code>L</code> lungimea totală a zidului, <code>n</code> numărul de unităţi ce urmează a fi acoperite şi <code>k</code> numărul maxim de panouri ce pot fi folosite. Pe a doua linie separate prin câte un spațiu sunt <code>n</code> valori <code>x1</code>, <code>x2</code>, … , <code>xn</code>, unde <code>xi</code> reprezintă unitatea din zid care este acoperită de un afiș vechi. Valorile <code>x1</code>, <code>x2</code>, … , <code>xn</code> apar într-o ordine aleatoare.
        panouri_folosite = n
 
    else:
= Date de ieșire =
        for i in range(n - k + 1):
Fișierul de ieșire <code>afiseOUT.txt</code> va conține o singură linie cu două valori <code>val Nk</code>, ce reprezintă lungimea minimă totală folosită și numărul de panouri folosite astfel încât toate zonele deteriorate să fie acoperite. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
            lungime_sectiune = unitati_deteriorate[i + k - 1] - unitati_deteriorate[i] + 1
 
            if lungime_sectiune > lungime_minima:
= Restricții și precizări =
                lungime_minima = lungime_sectiune
 
* <code>0 < L ≤ 1000</code>
* <code>0 < n ≤ L</code>
* <code>0 < k ≤ L / 2</code>
 
= Exemplul 1: =
<code>afiseIN.txt</code>
25 8 3
3 11 6 4 19 15 20 12
<code>afiseOUT.txt</code>
11 3
 
=== Explicație ===
Zidul are lungimea egală cu <code>25</code> de unități, iar <code>8</code> dintre ele conțin afișe care trebuiesc acoperite cu maximum <code>3</code> panouri. Se vor folosi toate cele <code>3</code> panouri care vor totaliza <code>11</code> unități, acoperind zonele <code>3-6</code>, <code>11-15</code> și <code>19-20</code>.
 
Caracterul <code>*</code> reprezintă unitățile de zid acoperite de afișe vechi


        panouri_folosite = min(n, k)
= Exemplul 2: =
<code>afiseIN.txt</code>
10 4 5
7 3 8 1
<code>afiseOUT.txt</code>
4 3


     return lungime_minima, panouri_folosite
== Rezolvare ==
<syntaxhighlight lang="python" line="1">
def verifica_restrictii(l, n, k):
     if not (0 < l <= 1000):
        return False
    if not (0 < n <= l):
        return False
    if not (0 < k <= l / 2):
        return False
    return True


def main():
def main():
     with open("afise.in", "r") as file_in:
     with open("afiseIN.txt", "r") as infile:
         L, n, k = map(int, file_in.readline().split())
         l, n, k = map(int, infile.readline().split())
         unitati_deteriorate = list(map(int, file_in.readline().split()))
         x_values = list(map(int, infile.readline().split()))
   
    if not verifica_restrictii(l, n, k):
        with open("afiseOUT.txt", "w") as outfile:
            outfile.write("Datele nu corespund restrictiilor impuse")
        return
   
    v = [0] * (l + 1)
    for x in x_values:
        v[x] = 1
   
    val = 0
    n1 = 0
    n2 = 0
    v1 = [0] * 1010
    v2 = [0] * 1010


     lungime_minima, panouri_folosite = acoperire_zid(L, n, k, unitati_deteriorate)
     i = 1
    while i <= l:
        if not v[i] and not n1:
            i += 1
        else:
            if not v[i]:
                n2 += 1
                while i <= l and not v[i]:
                    v2[n2] += 1
                    i += 1
            else:
                n1 += 1
                while i <= l and v[i] == 1:
                    v1[n1] += 1
                    i += 1
                    val += 1


     with open("afise.out", "w") as file_out:
    if not v[l]:
         file_out.write(f"{lungime_minima} {panouri_folosite}\n")
        n2 -= 1
 
    v2 = sorted(v2[1:n2 + 1])
   
    if n1 > k:
        nk = k
        for i in range(n1 - k):
            val += v2[i]
    else:
        nk = n1
 
     with open("afiseOUT.txt", "w") as outfile:
         outfile.write(f"{val} {nk}")


if __name__ == "__main__":
if __name__ == "__main__":
     main()
     main()
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 17:19, 18 May 2024

Campania electorală s-a terminat de mult, dar zidul din parcul central al oraşului în care au fost puse afişele este încă într-o formă dezolantă. Ploile şi vântul au acţionat şi au urâţit şi mai mult această zonă pe care altă dată erau afişe frumos colorate. Primăria a decis să se ocupe de această problemă. A format o comisie şi a decis realizarea unor panouri reclamă care să ascundă porţiunile deteriorate. Deoarece fondurile sunt mici s-a decis să fie alocate doar un anumit număr de panouri publicitare care trebuie să ocupe o suprafaţă cât mai mică posibil. Comisia a primit datele din teren sub forma: lungime zid, câte unităţi sunt ocupate cu afişe ce trebuie acoperite şi care este numărul de panouri pe care le poate folosi. De asemenea se primesc ca date şi care sunt unităţile de zid ocupate cu afişe deja deteriorate.

Cerința[edit | edit source]

Fiind date lungimea zidului, câte unităţi sunt deteriorate, care este numărul maxim de panouri ce pot fi folosite şi care sunt unităţile de zid deteriorate, se cere să se determine lungimea minimă totală a panourilor care sunt folosite pentru a acoperi zona şi câte panouri se folosesc. Lungimea minimă o definim ca numărul total de unităţi de zid acoperite astfel încât să fie mascate zonele problemă. Pentru acoperirea unităţilor de zid deteriorate, nu este neapărat necesar să se folosească toate panourile. Numărul de panouri folosite fiind limitat există posibilitatea să fie acoperite şi zone din zid care sunt curate.

Date de intrare[edit | edit source]

Fișierul de intrare afiseIN.txt conţine pe prima linie trei valori separate prin câte un spaţiu L n k, cu semnificația: L lungimea totală a zidului, n numărul de unităţi ce urmează a fi acoperite şi k numărul maxim de panouri ce pot fi folosite. Pe a doua linie separate prin câte un spațiu sunt n valori x1, x2, … , xn, unde xi reprezintă unitatea din zid care este acoperită de un afiș vechi. Valorile x1, x2, … , xn apar într-o ordine aleatoare.

Date de ieșire[edit | edit source]

Fișierul de ieșire afiseOUT.txt va conține o singură linie cu două valori val Nk, ce reprezintă lungimea minimă totală folosită și numărul de panouri folosite astfel încât toate zonele deteriorate să fie acoperite. Î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]

  • 0 < L ≤ 1000
  • 0 < n ≤ L
  • 0 < k ≤ L / 2

Exemplul 1:[edit | edit source]

afiseIN.txt

25 8 3
3 11 6 4 19 15 20 12

afiseOUT.txt

11 3

Explicație[edit | edit source]

Zidul are lungimea egală cu 25 de unități, iar 8 dintre ele conțin afișe care trebuiesc acoperite cu maximum 3 panouri. Se vor folosi toate cele 3 panouri care vor totaliza 11 unități, acoperind zonele 3-6, 11-15 și 19-20.

Caracterul * reprezintă unitățile de zid acoperite de afișe vechi

Exemplul 2:[edit | edit source]

afiseIN.txt

10 4 5
7 3 8 1

afiseOUT.txt

4 3

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1"> def verifica_restrictii(l, n, k):

   if not (0 < l <= 1000):
       return False
   if not (0 < n <= l):
       return False
   if not (0 < k <= l / 2):
       return False
   return True

def main():

   with open("afiseIN.txt", "r") as infile:
       l, n, k = map(int, infile.readline().split())
       x_values = list(map(int, infile.readline().split()))
   
   if not verifica_restrictii(l, n, k):
       with open("afiseOUT.txt", "w") as outfile:
           outfile.write("Datele nu corespund restrictiilor impuse")
       return
   
   v = [0] * (l + 1)
   for x in x_values:
       v[x] = 1
   
   val = 0
   n1 = 0
   n2 = 0
   v1 = [0] * 1010
   v2 = [0] * 1010
   i = 1
   while i <= l:
       if not v[i] and not n1:
           i += 1
       else:
           if not v[i]:
               n2 += 1
               while i <= l and not v[i]:
                   v2[n2] += 1
                   i += 1
           else:
               n1 += 1
               while i <= l and v[i] == 1:
                   v1[n1] += 1
                   i += 1
                   val += 1
   if not v[l]:
       n2 -= 1
   v2 = sorted(v2[1:n2 + 1])
   
   if n1 > k:
       nk = k
       for i in range(n1 - k):
           val += v2[i]
   else:
       nk = n1
   with open("afiseOUT.txt", "w") as outfile:
       outfile.write(f"{val} {nk}")

if __name__ == "__main__":

   main()

</syntaxhighlight>