0149 - Scara: Difference between revisions

From Bitnami MediaWiki
Pagină nouă: Claudia vrea să construiască o scară cu N trepte astfel încât prima treaptă să fie la înălţimea 0 şi ultima treaptă să fie la înălţimea H. Fiind pusă pe glume, ea îi cere arhitectului să proiecteze o scară neobişnuită, în care treptele sunt dispuse astfel încât, la un moment dat, să poţi urca, coborî sau rămâne la acelaşi nivel. Pentru a fi uşor de urcat sau coborât, valoarea absolută a diferenţei dintre înălţimile la care se află oricar...
 
No edit summary
Line 1: Line 1:
Claudia vrea să construiască o scară cu N trepte astfel încât prima treaptă să fie la înălţimea 0 şi ultima treaptă să fie la înălţimea H. Fiind pusă pe glume, ea îi cere arhitectului să proiecteze o scară neobişnuită, în care treptele sunt dispuse astfel încât, la un moment dat, să poţi urca, coborî sau rămâne la acelaşi nivel. Pentru a fi uşor de urcat sau coborât, valoarea absolută a diferenţei dintre înălţimile la care se află oricare două trepte consecutive trebuie să fie mai mică sau egală cu o valoare dată, K. Nicio treaptă nu se poate afla la o înălţime negativă sau la o înălţime mai mare decât H.
Claudia vrea să construiască o scară cu <code>N</code> trepte astfel încât prima treaptă să fie la înălţimea <code>0</code> şi ultima treaptă să fie la înălţimea <code>H</code>. Fiind pusă pe glume, ea îi cere arhitectului să proiecteze o scară neobişnuită, în care treptele sunt dispuse astfel încât, la un moment dat, să poţi urca, coborî sau rămâne la acelaşi nivel. Pentru a fi uşor de urcat sau coborât, valoarea absolută a diferenţei dintre înălţimile la care se află oricare două trepte consecutive trebuie să fie mai mică sau egală cu o valoare dată, <code>K</code>. Nicio treaptă nu se poate afla la o înălţime negativă sau la o înălţime mai mare decât <code>H</code>.
== Cerința ==
 
Scrieţi un program care să determine numărul de scări diferite cu N trepte, ce pot fi construite respectând cerinţele Claudiei. Deoarece numărul de scări poate fi foarte mare, determinaţi restul împărţirii acestui număr la 666013.
= Cerinţa =
== Date de intrare ==
Scrieţi un program care să determine numărul de scări diferite cu <code>N</code> trepte, ce pot fi construite respectând cerinţele Claudiei. Deoarece numărul de scări poate fi foarte mare, determinaţi restul împărţirii acestui număr la <code>666013</code>.
Pe prima linie a fişierului scarain.txt se află numerele naturale N H K, separate prin câte un spaţiu, cu semnificaţia din enunţ.
 
== Date de ieșire ==  
= Date de intrare =
Fişierul de ieşire scaraout.txt va conţine pe prima linie o valoare care reprezintă numărul cerut.
Pe prima linie a fişierului <code>scaraIN.txt</code> se află numerele naturale <code>N H K</code>, separate prin câte un spaţiu, cu semnificaţia din enunţ.
== Restricții și precizări ==
 
*1 ≤ N ≤ 109
= Date de ieşire =
*1 ≤ H ≤ 100
Fişierul de ieşire <code>scaraOUT.txt</code> va conţine pe prima linie o valoare care reprezintă numărul cerut.
*1 ≤ K ≤ H
 
*Pentru un număr de teste în valoare de 30 de puncte, N ≤ 20.000 şi H ≤ 20
= Restricţii şi precizări =
*Pentru un număr de teste în valoare de 50 de puncte, N ≤ 500.000 şi H ≤ 30
 
*Pentru un număr de teste în valoare de 80 de puncte, H ≤ 30
* <code>1 ≤ N ≤ 109</code>
== Exemplul 1 ==
* <code>1 ≤ H ≤ 100</code>
; scarain.txt
* <code>1 ≤ K ≤ H</code>
: 4 3 2
* Pentru un număr de teste în valoare de 30 de puncte, <code>N ≤ 20.000</code> şi <code>H ≤ 20</code>
; scaraout.txt
* Pentru un număr de teste în valoare de 50 de puncte, <code>N ≤ 500.000</code> şi <code>H ≤ 30</code>
: 8
* Pentru un număr de teste în valoare de 80 de puncte, <code>H ≤ 30</code>
<br>
 
== Exemplul 2 ==
= Exemplu 1: =
; scarain.txt
<code>scaraIN.txt</code>
: 5 4 2
4 3 2
; scaraout.txt
<code>scaraOUT.txt</code>
: 34
8
<br>
 
== Rezolvare ==
= Explicație =
<syntaxhighlight lang="python" line>
0 0 1 3
#0149 - Scara
 
def count_stairs(N, H, K):
0 2 3 3
    mod = 666013
 
    dp = [[0] * (H + 1) for _ in range(N + 1)]
0 1 2 3
 
0 1 3 3
 
0 2 1 3
 
0 0 2 3
 
0 1 1 3


    # Inițializăm cazurile de bază
0 2 2 3
    dp[0][0] = 1


    # Calculăm numărul de modalități folosind programarea dinamică
= Exemplu 2: =
    for i in range(1, N + 1):
<code>scaraIN.txt</code>
        for j in range(1, H + 1):
4 3 4
            dp[i][j] = sum(dp[i - 1][max(0, j - K + 1):j]) % mod
<code>scaraOUT.txt</code>
Datele nu corespund restrictiilor impuse


    return sum(dp[N]) % mod
== Rezolvare ==
<syntaxhighlight lang="python" line="1">
HMAX = 105
MOD = 666013


# Citirea datelor de intrare
def mul(A, B, h):
with open("scarain.txt", "r") as infile:
     C = [[0] * HMAX for _ in range(HMAX)]
     N, H, K = map(int, infile.readline().split())
    for i in range(h + 1):
        for j in range(h + 1):
            sum = 0
            for k in range(h + 1):
                sum += A[i][k] * B[k][j]
            C[i][j] = sum % MOD
    for i in range(h + 1):
        for j in range(h + 1):
            A[i][j] = C[i][j]


# Verificarea restricțiilor
def main():
if not (1 <= N <= 10**9 and 1 <= H <= 100 and 1 <= K <= H):
    with open("scaraIN.txt", "r") as infile:
    print("Fals")
        n, h, k = map(int, infile.readline().strip().split())
else:
   
     # Calculul rezultatului
    if not (1 <= n <= 10**9) or not (1 <= h <= 100) or not (1 <= k <= h):
     result = count_stairs(N, H, K)
        with open("scaraOUT.txt", "w") as outfile:
            outfile.write("Datele nu corespund restrictiilor impuse\n")
        return
   
    A = [[0] * HMAX for _ in range(HMAX)]
    P = [[0] * HMAX for _ in range(HMAX)]
   
    for j in range(h + 1):
        A[j][j] = 1
        for i in range(h + 1):
            if j - k <= i <= j + k:
                P[i][j] = 1
      
     n -= 1
    while n:
        if n & 1:
            mul(A, P, h)
        mul(P, P, h)
        n >>= 1
   
    with open("scaraOUT.txt", "w") as outfile:
        outfile.write(f"{A[0][h]}\n")


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


</syntaxhighlight>
</syntaxhighlight>

Revision as of 06:46, 18 May 2024

Claudia vrea să construiască o scară cu N trepte astfel încât prima treaptă să fie la înălţimea 0 şi ultima treaptă să fie la înălţimea H. Fiind pusă pe glume, ea îi cere arhitectului să proiecteze o scară neobişnuită, în care treptele sunt dispuse astfel încât, la un moment dat, să poţi urca, coborî sau rămâne la acelaşi nivel. Pentru a fi uşor de urcat sau coborât, valoarea absolută a diferenţei dintre înălţimile la care se află oricare două trepte consecutive trebuie să fie mai mică sau egală cu o valoare dată, K. Nicio treaptă nu se poate afla la o înălţime negativă sau la o înălţime mai mare decât H.

Cerinţa

Scrieţi un program care să determine numărul de scări diferite cu N trepte, ce pot fi construite respectând cerinţele Claudiei. Deoarece numărul de scări poate fi foarte mare, determinaţi restul împărţirii acestui număr la 666013.

Date de intrare

Pe prima linie a fişierului scaraIN.txt se află numerele naturale N H K, separate prin câte un spaţiu, cu semnificaţia din enunţ.

Date de ieşire

Fişierul de ieşire scaraOUT.txt va conţine pe prima linie o valoare care reprezintă numărul cerut.

Restricţii şi precizări

  • 1 ≤ N ≤ 109
  • 1 ≤ H ≤ 100
  • 1 ≤ K ≤ H
  • Pentru un număr de teste în valoare de 30 de puncte, N ≤ 20.000 şi H ≤ 20
  • Pentru un număr de teste în valoare de 50 de puncte, N ≤ 500.000 şi H ≤ 30
  • Pentru un număr de teste în valoare de 80 de puncte, H ≤ 30

Exemplu 1:

scaraIN.txt

4 3 2

scaraOUT.txt

8

Explicație

0 0 1 3

0 2 3 3

0 1 2 3

0 1 3 3

0 2 1 3

0 0 2 3

0 1 1 3

0 2 2 3

Exemplu 2:

scaraIN.txt

4 3 4

scaraOUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare

<syntaxhighlight lang="python" line="1"> HMAX = 105 MOD = 666013

def mul(A, B, h):

   C = [[0] * HMAX for _ in range(HMAX)]
   for i in range(h + 1):
       for j in range(h + 1):
           sum = 0
           for k in range(h + 1):
               sum += A[i][k] * B[k][j]
           C[i][j] = sum % MOD
   for i in range(h + 1):
       for j in range(h + 1):
           A[i][j] = C[i][j]

def main():

   with open("scaraIN.txt", "r") as infile:
       n, h, k = map(int, infile.readline().strip().split())
   
   if not (1 <= n <= 10**9) or not (1 <= h <= 100) or not (1 <= k <= h):
       with open("scaraOUT.txt", "w") as outfile:
           outfile.write("Datele nu corespund restrictiilor impuse\n")
       return
   
   A = [[0] * HMAX for _ in range(HMAX)]
   P = [[0] * HMAX for _ in range(HMAX)]
   
   for j in range(h + 1):
       A[j][j] = 1
       for i in range(h + 1):
           if j - k <= i <= j + k:
               P[i][j] = 1
   
   n -= 1
   while n:
       if n & 1:
           mul(A, P, h)
       mul(P, P, h)
       n >>= 1
   
   with open("scaraOUT.txt", "w") as outfile:
       outfile.write(f"{A[0][h]}\n")

if __name__ == "__main__":

   main()

</syntaxhighlight>

Explicatie

0 0 1 3 0 2 3 3 0 1 2 3 0 1 3 3 0 2 1 3 0 0 2 3 0 1 1 3 0 2 2 3