3357 - beta: Difference between revisions
No edit summary |
No edit summary |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 10: | Line 10: | ||
== Date de ieșire == | == Date de ieșire == | ||
Dacă datele sunt introduse corect, pe ecran se va afișa: | Dacă datele sunt introduse corect, pe ecran se va afișa: | ||
'''"Datele sunt introduse corect."''', apoi | '''"Datele sunt introduse corect."''', apoi ''' fișierul beta.out va conține valoarea cerută. Dacă șirul B are mai puțin de poz elemente se va scrie în fișier -1.''', reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: '''"Datele nu corespund restricțiilor impuse."'''. | ||
== Restricţii şi precizări == | == Restricţii şi precizări == | ||
Line 19: | Line 19: | ||
* 1 ≤ poz ≤ 2.000.000.000 | * 1 ≤ poz ≤ 2.000.000.000 | ||
* Pentru 55 de puncte avem n ≤ 100.000 | * Pentru 55 de puncte avem n ≤ 100.000 | ||
== Exemplu == | == Exemplu 1 == | ||
; Intrare | ; Intrare | ||
: beta.in | |||
: 8 13 | : 8 13 | ||
; Ieșire | ; Ieșire | ||
: Datele sunt introduse correct. | : Datele sunt introduse correct. | ||
: beta.out | |||
: 7 | : 7 | ||
== Exemplu 2 == | |||
; Intrare | |||
: beta.in | |||
: 8 25 | |||
; Ieșire | |||
: Datele nu corespund restricțiilor impuse. | |||
== Rezolvare == | == Rezolvare == | ||
Line 31: | Line 42: | ||
<syntaxhighlight lang="python" line> | <syntaxhighlight lang="python" line> | ||
# 3357 - beta | # 3357 - beta | ||
def | def calc_b(n, k): | ||
b = list(range(1, n+1)) | |||
p = n | |||
while | while p > 1: | ||
p //= 2 | |||
q = n // p | |||
r = n % p | |||
if r == 0: | |||
r = p | |||
q -= 1 | |||
start = n - q*p + 1 | |||
end = start + r - 1 | |||
if q % 2 == 1: | |||
return | b.extend(reversed(range(start, end+1))) | ||
else: | |||
b.extend(range(start, end+1)) | |||
return b | |||
def validate_input(n, k): | |||
if not (1 <= n <= 10**5 and 1 <= k <= n): | |||
return False | |||
return True | |||
if __name__ == '__main__': | |||
with open('beta.in', 'r') as f_in, open('beta.out', 'w') as f_out: | |||
n, k = map(int, f_in.readline().split()) | |||
if not validate_input(n, k): | |||
f_out.write('-1\n') | |||
print('Datele nu corespund restricțiilor impuse.') | |||
else: | |||
b = calc_b(n, k) | |||
f_out.write(f'{b[k-1]}\n') | |||
Line 66: | Line 82: | ||
== Explicatie Rezolvare == | == Explicatie Rezolvare == | ||
Funcția | Funcția `calc_b` primește două argumente: `n`, care este numărul dat, și `k`, care este poziția cerută în șirul `B`. Funcția începe prin construirea șirului `A`, care este un șir ordonat de la 1 la `n`. Apoi se împarte `n` la 2, apoi la 4, apoi la 8, și așa mai departe, până când nu se mai poate împărți. Se păstrează ultimele `n/p` elemente din șirul `A`, și acestea sunt adăugate la șirul `B` în ordinea cerută. Dacă `n` nu se divide exact la `p`, atunci se ia o bucată mai mică din șirul `A` și se adaugă la șirul `B` în ordinea cerută. Funcția se termină returnând șirul `B`. | ||
Funcția | Funcția `validate_input` primește aceiași doi parametri ca și `calc_b` și verifică dacă aceștia îndeplinesc condițiile date în enunțul problemei. Dacă nu se îndeplinesc, returnează `False`, altfel returnează `True`. | ||
Funcția `main` citește datele de intrare din fișierul `beta.in`, validează datele, calculează șirul `B` folosind funcția `calc_b`, și scrie în fișierul `beta.out` numărul de pe poziția `k` din șirul `B`. Dacă datele nu sunt valide, se scrie `-1` în fișierul `beta.out` și se afișează un mesaj de eroare. |
Latest revision as of 21:03, 14 May 2023
Sursa: - beta
Cerinţa[edit | edit source]
Se dă un număr natural n despre care se cunoaște că este putere de 2. Considerăm inițial șirul numerelor naturale de la 1 la n așezate în ordine crescătoare. Notăm cu A acest șir. Pornind de la acesta, se construiește un nou șir (să îl notăm cu B) astfel: Primele n elemente ale lui B sunt chiar elementele șirului A în aceeași ordine. Următoarele n/2 elemente ale lui B sunt ultimele n/2 elemente ale lui A dar scrise în ordine inversă (descrescător). Următoarele n/4 elemente ale lui B sunt ultimele n/4 elemente ale lui A scrise în ordine crescătoare, următoarele n/8 elemente ale lui B sunt ultimele n/8 elemente ale lui A scrise în ordine descrescătoare, și tot așa, cu fiecare putere de 2 (notată p) ce apare la numitor, luăm ultimele n/p elemente din A și le adăugăm la finalul lui B alternând ordinea de parcurgere, de la o putere la alta conform modului descris mai sus. Se mai să un număr poz. Se cere determinarea numărului de pe poziția poz din șirul B.
Date de intrare[edit | edit source]
Fișierul beta.in conține pe prima linie numerele naturale n și poz separate printr-un spațiu.
Date de ieșire[edit | edit source]
Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect.", apoi fișierul beta.out va conține valoarea cerută. Dacă șirul B are mai puțin de poz elemente se va scrie în fișier -1., reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".
Restricţii şi precizări[edit | edit source]
- 1 ≤ n ≤ 1.000.000.000
- n se dă putere de 2
- 1 ≤ poz ≤ 2.000.000.000
- Pentru 55 de puncte avem n ≤ 100.000
Exemplu 1[edit | edit source]
- Intrare
- beta.in
- 8 13
- Ieșire
- Datele sunt introduse correct.
- beta.out
- 7
Exemplu 2[edit | edit source]
- Intrare
- beta.in
- 8 25
- Ieșire
- Datele nu corespund restricțiilor impuse.
Rezolvare[edit | edit source]
Rezolvare ver. 1[edit | edit source]
<syntaxhighlight lang="python" line>
- 3357 - beta
def calc_b(n, k):
b = list(range(1, n+1)) p = n while p > 1: p //= 2 q = n // p r = n % p if r == 0: r = p q -= 1 start = n - q*p + 1 end = start + r - 1 if q % 2 == 1: b.extend(reversed(range(start, end+1))) else: b.extend(range(start, end+1)) return b
def validate_input(n, k):
if not (1 <= n <= 10**5 and 1 <= k <= n): return False return True
if __name__ == '__main__':
with open('beta.in', 'r') as f_in, open('beta.out', 'w') as f_out: n, k = map(int, f_in.readline().split()) if not validate_input(n, k): f_out.write('-1\n') print('Datele nu corespund restricțiilor impuse.') else: b = calc_b(n, k) f_out.write(f'{b[k-1]}\n')
</syntaxhighlight>
Explicatie Rezolvare[edit | edit source]
Funcția `calc_b` primește două argumente: `n`, care este numărul dat, și `k`, care este poziția cerută în șirul `B`. Funcția începe prin construirea șirului `A`, care este un șir ordonat de la 1 la `n`. Apoi se împarte `n` la 2, apoi la 4, apoi la 8, și așa mai departe, până când nu se mai poate împărți. Se păstrează ultimele `n/p` elemente din șirul `A`, și acestea sunt adăugate la șirul `B` în ordinea cerută. Dacă `n` nu se divide exact la `p`, atunci se ia o bucată mai mică din șirul `A` și se adaugă la șirul `B` în ordinea cerută. Funcția se termină returnând șirul `B`.
Funcția `validate_input` primește aceiași doi parametri ca și `calc_b` și verifică dacă aceștia îndeplinesc condițiile date în enunțul problemei. Dacă nu se îndeplinesc, returnează `False`, altfel returnează `True`.
Funcția `main` citește datele de intrare din fișierul `beta.in`, validează datele, calculează șirul `B` folosind funcția `calc_b`, și scrie în fișierul `beta.out` numărul de pe poziția `k` din șirul `B`. Dacă datele nu sunt valide, se scrie `-1` în fișierul `beta.out` și se afișează un mesaj de eroare.