0149 - Scara

De la Universitas MediaWiki
Versiunea pentru tipărire nu mai este suportată și poate avea erori de randare. Vă rugăm să vă actualizați bookmarkurile browserului și să folosiți funcția implicită de tipărire a browserului.

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. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

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

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()

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