2972 - Rufe: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: Alex vrea să își usuce rufele pe balcon. El a spălat K tricouri și o șosetă. Uscătorul lui Alex are N niveluri, iar fiecare nivel are M locuri unde poate atârna câte un singur obiect de îmbrăcăminte. Alex usucă hainele într-un mod specific: începe prin a pune șoseta pe nivelul A, locul B, iar apoi aduce coșul de rufe cu cele K tricouri și le așază pe rând, mereu alegând o poziție liberă cât mai depărtată de locul unde a pus șoseta. Metrica pe care...
 
No edit summary
 
Line 1: Line 1:
Alex vrea să își usuce rufele pe balcon. El a spălat K tricouri și o șosetă. Uscătorul lui Alex are N niveluri, iar fiecare nivel are M locuri unde poate atârna câte un singur obiect de îmbrăcăminte. Alex usucă hainele într-un mod specific: începe prin a pune șoseta pe nivelul A, locul B, iar apoi aduce coșul de rufe cu cele K tricouri și le așază pe rând, mereu alegând o poziție liberă cât mai depărtată de locul unde a pus șoseta. Metrica pe care o găsește ca fiind cea mai potrivită când vine vorba de uscatul rufelor este distanța Manhattan, astfel încât distanța de la nivelul r1, locul c1 la nivelul r2, locul c2 are valoarea expresiei |r1 – r2| + |c1 - c2|.
 
== Cerința ==
Alex vrea să își usuce rufele pe balcon. El a spălat <code>K</code> tricouri și o șosetă. Uscătorul lui Alex are <code>N</code> niveluri, iar fiecare nivel are <code>M</code> locuri unde poate atârna câte un singur obiect de îmbrăcăminte. Alex usucă hainele într-un mod specific: începe prin a pune șoseta pe nivelul <code>A</code>, locul <code>B</code>, iar apoi aduce coșul de rufe cu cele <code>K</code> tricouri și le așază pe rând, mereu alegând o poziție liberă cât mai depărtată de locul unde a pus șoseta. Metrica pe care o găsește ca fiind cea mai potrivită când vine vorba de uscatul rufelor este distanța Manhattan, astfel încât distanța de la nivelul <code>r1</code>, locul <code>c1</code> la nivelul <code>r2</code>, locul <code>c2</code> are valoarea expresiei <code>|r1 – r2| + |c1 - c2|</code>.
 
= Cerința =
Aflați distanța dintre poziția unde a atârnat ultimul tricou și poziția unde se usucă șoseta.
Aflați distanța dintre poziția unde a atârnat ultimul tricou și poziția unde se usucă șoseta.
== Date de intrare ==
 
Pe prima linie a fișierului de intrare rufein.txt se vor afla 5 numere întregi N, M, A, B, și K, cu semnificația din enunț, separate prin câte un spațiu.
= Date de intrare =
== Date de ieșire ==  
Pe prima linie a fișierului de intrare <code>rufeIN.txt</code> se vor afla <code>5</code> numere întregi <code>N</code>, <code>M</code>, <code>A</code>, <code>B</code>, și <code>K</code>, cu semnificația din enunț, separate prin câte un spațiu.
În fișierul de ieșire rufeout.txt se va afla o singură linie care să conțină valoarea cerută.
 
== Restricții și precizări ==
= Date de ieșire =
*1 ≤ N, M ≤ 1.000.000.000
În fișierul de ieșire <code>rufeOUT.txt</code> se va afla o singură linie care să conțină valoarea cerută. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
*1 ≤ A ≤ N
 
*1 ≤ B ≤ M
= Restricții și precizări =
*1 ≤ K ≤ N * M – 1
 
*Pentru teste în valoare de 13 puncte se garantează că N, M ≤ 1.000.
* <code>1 ≤ N, M ≤ 1.000.000.000</code>
*Pentru alte teste în valoare de 12 puncte se garantează că N ≤ 1.000.000.
* <code>1 ≤ A ≤ N</code>
*Pentru alte teste în valoare de 12 puncte se garantează că M ≤ 1.000.000.
* <code>1 ≤ B ≤ M</code>
*Pentru alte teste în valoare de 18 puncte se garantează că K ≤ 1.000.000.
* <code>1 ≤ K ≤ N * M – 1</code>
*Pentru alte teste în valoare de 7 puncte se garantează că A = B = 1.
* Pentru teste în valoare de <code>13</code> puncte se garantează că <code>N, M ≤ 1.000</code>.
== Exemplul 1 ==
* Pentru alte teste în valoare de <code>12</code> puncte se garantează că <code>N ≤ 1.000.000</code>.
; rufein.txt
* Pentru alte teste în valoare de <code>12</code> puncte se garantează că <code>M ≤ 1.000.000</code>.
: 5 6 3 3 4
* Pentru alte teste în valoare de <code>18</code> puncte se garantează că <code>K ≤ 1.000.000</code>.
; rufeout.txt
* Pentru alte teste în valoare de <code>7</code> puncte se garantează că <code>A = B = 1</code>.
: 4
 
<br>
= Exemplul 1: =
== Explicatie ==
<code>rufeIN.txt</code>
Uscătorul are 5 niveluri cu câte 6 locuri pe nivel. Șoseta se pune pe nivelul 3, locul 3. Primele 2 tricouri vor fi atârnate la distanță 5 în colțurile uscătorului. Următoarele 2 tricouri pot fi puse numai la distanță 4.
5 6 3 3 4
== Exemplul 2 ==
<code>rufeOUT.txt</code>
; rufein.txt
4
: 3476 53410 438 9217 1000000
 
; rufeout.txt
=== Explicație ===
: 45818
Uscătorul are <code>5</code> niveluri cu câte <code>6</code> locuri pe nivel. Șoseta se pune pe nivelul <code>3</code>, locul <code>3</code>. Primele <code>2</code> tricouri vor fi atârnate la distanță <code>5</code> în colțurile uscătorului. Următoarele <code>2</code> tricouri pot fi puse numai la distanță <code>4</code>.
<br>
 
== Explicatie ==  
= Exemplul 2: =
În acest caz Alex usucă 10**10 tricouri. Acordați atenție citirii unei astfel de valori din fișier.
<code>rufeIN.txt</code>
3476 53410 438 9217 1000000
<code>rufeOUT.txt</code>
45818
 
= Exemplul 2: =
<code>rufeIN.txt</code>
5 6 3 8 4
<code>rufeOUT.txt</code>
Datele nu corespund restrictiilor impuse
 
== Rezolvare ==  
== Rezolvare ==  
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line="1">
#2972 - Rufe
def check_constraints(n, m, x, y, k):
def calculate_manhattan_distance(N, M, A, B, K):
     if not (1 <= n <= 1_000_000_000 and 1 <= m <= 1_000_000_000):
     if not (1 <= N <= 1000000000 and 1 <= M <= 1000000000 and 1 <= A <= N and 1 <= B <= M and 1 <= K <= N * M - 1):
        return False
         print("Fals")
    if not (1 <= x <= n and 1 <= y <= m):
        return False
    if not (1 <= k <= n * m - 1):
         return False
    return True
 
def unwrap(a):
    return max(a, 0)
 
def sum_from_to(from_, to, i0):
    if from_ > to:
         return 0
         return 0
    return (to - from_ + 2 * i0) * (to - from_ + 1) // 2
def count_corner(x, y, d, n, m):
    return (sum_from_to(unwrap(x + d - n), min(d, m - y), unwrap(n - x - d) + 1)
            + unwrap(m - y - d) * (n - x + 1))


     tricouri_atarnate = K // M
def count_greater_equal(x, y, d, n, m, k):
    rest_tricouri = K % M
     if d == 0:
        return n * m


     nivel_ultim_tricou = tricouri_atarnate + 1
     return (count_corner(x, y, d, n, m) + count_corner(n - x + 1, m - y + 1, d, n, m)
    loc_ultim_tricou = B + rest_tricouri
            + count_corner(n - x + 1, y, d, n, m) + count_corner(x, m - y + 1, d, n, m)
            - unwrap(x - d) - unwrap(y - d) - unwrap(n - (x + d - 1)) - unwrap(m - (y + d - 1)))


     distanta_manhattan = abs(A - nivel_ultim_tricou) + abs(B - loc_ultim_tricou)
def main():
     with open('rufeIN.txt', 'r') as f:
        n, m, x, y, k = map(int, f.read().strip().split())


     return distanta_manhattan
     # Check constraints
    if not check_constraints(n, m, x, y, k):
        with open('rufeOUT.txt', 'w') as f:
            f.write("Datele nu corespund restrictiilor impuse\n")
        return


# Citirea datelor de intrare
    l, r = -1, n + m - 1
with open("rufein.txt", "r") as infile:
    while r - l > 1:
    N, M, A, B, K = map(int, infile.readline().split())
        p = (l + r) // 2
        if count_greater_equal(x, y, p, n, m, k) < k:
            r = p
        else:
            l = p


# Calculul rezultatului
    with open('rufeOUT.txt', 'w') as f:
result = calculate_manhattan_distance(N, M, A, B, K)
        f.write(f"{l}\n")


# Scrierea rezultatului în fișierul de ieșire
if __name__ == '__main__':
if result:
     main()
     with open("rufeout.txt", "w") as outfile:
        outfile.write(str(result) + '\n')


</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 06:08, 18 May 2024

Alex vrea să își usuce rufele pe balcon. El a spălat K tricouri și o șosetă. Uscătorul lui Alex are N niveluri, iar fiecare nivel are M locuri unde poate atârna câte un singur obiect de îmbrăcăminte. Alex usucă hainele într-un mod specific: începe prin a pune șoseta pe nivelul A, locul B, iar apoi aduce coșul de rufe cu cele K tricouri și le așază pe rând, mereu alegând o poziție liberă cât mai depărtată de locul unde a pus șoseta. Metrica pe care o găsește ca fiind cea mai potrivită când vine vorba de uscatul rufelor este distanța Manhattan, astfel încât distanța de la nivelul r1, locul c1 la nivelul r2, locul c2 are valoarea expresiei |r1 – r2| + |c1 - c2|.

Cerința[edit | edit source]

Aflați distanța dintre poziția unde a atârnat ultimul tricou și poziția unde se usucă șoseta.

Date de intrare[edit | edit source]

Pe prima linie a fișierului de intrare rufeIN.txt se vor afla 5 numere întregi N, M, A, B, și K, cu semnificația din enunț, separate prin câte un spațiu.

Date de ieșire[edit | edit source]

În fișierul de ieșire rufeOUT.txt se va afla o singură linie care să conțină valoarea cerută. Î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]

  • 1 ≤ N, M ≤ 1.000.000.000
  • 1 ≤ A ≤ N
  • 1 ≤ B ≤ M
  • 1 ≤ K ≤ N * M – 1
  • Pentru teste în valoare de 13 puncte se garantează că N, M ≤ 1.000.
  • Pentru alte teste în valoare de 12 puncte se garantează că N ≤ 1.000.000.
  • Pentru alte teste în valoare de 12 puncte se garantează că M ≤ 1.000.000.
  • Pentru alte teste în valoare de 18 puncte se garantează că K ≤ 1.000.000.
  • Pentru alte teste în valoare de 7 puncte se garantează că A = B = 1.

Exemplul 1:[edit | edit source]

rufeIN.txt

5 6 3 3 4

rufeOUT.txt

4

Explicație[edit | edit source]

Uscătorul are 5 niveluri cu câte 6 locuri pe nivel. Șoseta se pune pe nivelul 3, locul 3. Primele 2 tricouri vor fi atârnate la distanță 5 în colțurile uscătorului. Următoarele 2 tricouri pot fi puse numai la distanță 4.

Exemplul 2:[edit | edit source]

rufeIN.txt

3476 53410 438 9217 1000000

rufeOUT.txt

45818

Exemplul 2:[edit | edit source]

rufeIN.txt

5 6 3 8 4

rufeOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line="1"> def check_constraints(n, m, x, y, k):

   if not (1 <= n <= 1_000_000_000 and 1 <= m <= 1_000_000_000):
       return False
   if not (1 <= x <= n and 1 <= y <= m):
       return False
   if not (1 <= k <= n * m - 1):
       return False
   return True

def unwrap(a):

   return max(a, 0)

def sum_from_to(from_, to, i0):

   if from_ > to:
       return 0
   return (to - from_ + 2 * i0) * (to - from_ + 1) // 2

def count_corner(x, y, d, n, m):

   return (sum_from_to(unwrap(x + d - n), min(d, m - y), unwrap(n - x - d) + 1)
           + unwrap(m - y - d) * (n - x + 1))

def count_greater_equal(x, y, d, n, m, k):

   if d == 0:
       return n * m
   return (count_corner(x, y, d, n, m) + count_corner(n - x + 1, m - y + 1, d, n, m)
           + count_corner(n - x + 1, y, d, n, m) + count_corner(x, m - y + 1, d, n, m)
           - unwrap(x - d) - unwrap(y - d) - unwrap(n - (x + d - 1)) - unwrap(m - (y + d - 1)))

def main():

   with open('rufeIN.txt', 'r') as f:
       n, m, x, y, k = map(int, f.read().strip().split())
   # Check constraints
   if not check_constraints(n, m, x, y, k):
       with open('rufeOUT.txt', 'w') as f:
           f.write("Datele nu corespund restrictiilor impuse\n")
       return
   l, r = -1, n + m - 1
   while r - l > 1:
       p = (l + r) // 2
       if count_greater_equal(x, y, p, n, m, k) < k:
           r = p
       else:
           l = p
   with open('rufeOUT.txt', 'w') as f:
       f.write(f"{l}\n")

if __name__ == '__main__':

   main()

</syntaxhighlight>