2405 - politic: Diferență între versiuni

De la Universitas MediaWiki
(Pagină nouă: Sursa: [https://www.pbinfo.ro/probleme/304/secvente 2405 - politic] ---- În Țara lui Papură Vodă s-au organizat de curând primele alegeri democratice. A rezultat astfel un parlament din care fac parte deputați cu diverse doctrine politice, de stânga sau de dreapta. Acestea sunt descrise prin numere naturale nenule (orientarea politică este cu atât mai de stânga cu cât numărul este mai mic). Parlamentarii s-au asociat în partide politice în funcție de doctrina f...)
 
Fără descriere a modificării
 
(Nu s-au afișat 3 versiuni intermediare efectuate de un alt utilizator)
Linia 1: Linia 1:
Sursa: [https://www.pbinfo.ro/probleme/304/secvente 2405 - politic]
Sursa: [https://www.pbinfo.ro/probleme/304/secvente 2405 - politic]
----
----
== Cerinţa ==
În Țara lui Papură Vodă s-au organizat de curând primele alegeri democratice. A rezultat astfel un parlament din care fac parte deputați cu diverse doctrine politice, de stânga sau de dreapta. Acestea sunt descrise prin numere naturale nenule (orientarea politică este cu atât mai de stânga cu cât numărul este mai mic). Parlamentarii s-au asociat în partide politice în funcție de doctrina fiecăruia. Oricare doi deputați ale căror doctrine corespund unor numere consecutive fac parte din același partid. Prin urmare, partidele vor fi alcătuite din deputați ale căror doctrine sunt numere consecutive. (De exemplu, dacă parlamentul are 5 deputați, cu doctrinele 1, 2, 3, 5 şi 6, atunci înseamnă că aceștia sunt grupați în două partide: unul format din 1, 2 și 3 și altul din 5 și 6.)
În Țara lui Papură Vodă s-au organizat de curând primele alegeri democratice. A rezultat astfel un parlament din care fac parte deputați cu diverse doctrine politice, de stânga sau de dreapta. Acestea sunt descrise prin numere naturale nenule (orientarea politică este cu atât mai de stânga cu cât numărul este mai mic). Parlamentarii s-au asociat în partide politice în funcție de doctrina fiecăruia. Oricare doi deputați ale căror doctrine corespund unor numere consecutive fac parte din același partid. Prin urmare, partidele vor fi alcătuite din deputați ale căror doctrine sunt numere consecutive. (De exemplu, dacă parlamentul are 5 deputați, cu doctrinele 1, 2, 3, 5 şi 6, atunci înseamnă că aceștia sunt grupați în două partide: unul format din 1, 2 și 3 și altul din 5 și 6.)
Un guvern trebuie să beneficieze de susținerea a mai mult de jumătate dintre parlamentari. De exemplu, dacă parlamentul este format din 7 deputați, atunci un guvern are nevoie de susținerea a cel puțin 4 deputați.
Un guvern trebuie să beneficieze de susținerea a mai mult de jumătate dintre parlamentari. De exemplu, dacă parlamentul este format din 7 deputați, atunci un guvern are nevoie de susținerea a cel puțin 4 deputați.
Pentru a putea guverna, partidele se pot grupa in coaliţii. Regula după care se asociază este urmatoarea: două partide A şi B, A având o doctrină mai de stânga, pot face parte din aceeași coaliţie doar dacă din coaliţia respectivă fac parte toate partidele a căror doctrină este mai de dreapta decât cea a lui A şi mai de stânga decât cea a lui B. De exemplu, dacă parlamentul este alcătuit din deputaţi cu orientările politice 1, 2, 4, 5, 7 şi 8, atunci partidul format din 1 şi 2 nu se poate asocia cu partidul format din 7 şi 8 decât dacă din coaliţia respectivă face parte şi partidul format din 4 şi 5.
Pentru a putea guverna, partidele se pot grupa in coaliţii. Regula după care se asociază este urmatoarea: două partide A şi B, A având o doctrină mai de stânga, pot face parte din aceeași coaliţie doar dacă din coaliţia respectivă fac parte toate partidele a căror doctrină este mai de dreapta decât cea a lui A şi mai de stânga decât cea a lui B. De exemplu, dacă parlamentul este alcătuit din deputaţi cu orientările politice 1, 2, 4, 5, 7 şi 8, atunci partidul format din 1 şi 2 nu se poate asocia cu partidul format din 7 şi 8 decât dacă din coaliţia respectivă face parte şi partidul format din 4 şi 5.
== Cerinţa ==
Fiind dat parlamentul din Ţara lui Papură Vodă printr-un şir ordonat strict crescător de numere naturale nenule, se cere să se stabilească numărul de partide parlamentare şi numărul variantelor de coaliţie majoritară.
Fiind dat parlamentul din Ţara lui Papură Vodă printr-un şir ordonat strict crescător de numere naturale nenule, se cere să se stabilească numărul de partide parlamentare şi numărul variantelor de coaliţie majoritară.


Linia 14: Linia 15:


== Date de ieșire ==  
== Date de ieșire ==  
Fișierul de ieșire politic.out va conține pe prima linie un număr natural nenul X, reprezentând numărul de partide din parlament, iar a doua linie va conține un alt număr natural nenul Y care reprezintă numărul de coaliții majoritare care se pot forma.
 
Dacă datele sunt introduse corect, pe ecran se va afișa:
'''"Datele sunt introduse corect."''', fișierul de ieșire politic.out conține prima linie numărul C, reprezentând numărul de secvenţe cu elementele ordonate crescător din şirul dat''', 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 ==
* 0 < N ≤ 20.000
* 0 < N ≤ 20.000
* numerele din șir sunt mai mici sau egale cu 30.000
* numerele din șir sunt mai mici sau egale cu 30.000
== Exemplu ==
== Exemplu 1 ==
; Intrare
; Intrare
: politic.in
: 10
: 10
: 1 2 3 5 6 8 10 11 14 15  
: 1 2 3 5 6 8 10 11 14 15  
; Ieșire
; Ieșire
: Datele sunt introduse correct.
: politic.out
: 5  
: 5  
: 4
: 4
== Exemplu 2 ==
; Intrare
: politic.in
: 20
: 0 7 8 9 1 2 3 4 5
; Ieșire
: Datele nu corespund restricțiilor impuse.


== Rezolvare ==  
== Rezolvare ==  
Linia 32: Linia 46:
# 2405 - politic
# 2405 - politic


def read_input():
def validate_input(n, arr):
     n = int(input())
     if n <= 0 or n > 20000:
     parties = list(map(int, input().split()))
        return False
     return n, parties
    if any(x <= 0 or x > 30000 for x in arr):
        return False
    return True
 
def count_sequences(arr):
    cnt = 1
     max_cnt = 1
    for i in range(1, len(arr)):
        if arr[i] > arr[i-1]:
            cnt += 1
            if cnt > max_cnt:
                max_cnt = cnt
        else:
            cnt = 1
     return max_cnt


def solve(n, parties):
def count_coalitions(arr):
     # numărul de partide
     cnt = 0
    num_parties = 0
     for i in range(len(arr)):
     for i in range(n):
         for j in range(i+1, len(arr)):
        if i == 0 or parties[i] - parties[i-1] > 1:
             diff = abs(arr[i] - arr[j])
            num_parties += 1
            if diff == 1:
    # numărul de coaliții majoritare
                 break
    num_majority_coalitions = 0
            else:
    for i in range(num_parties):
                 for k in range(i+1, j):
         for j in range(i+1, num_parties):
                    if abs(arr[k] - arr[i]) > diff and abs(arr[k] - arr[j]) > diff:
             if parties[j] - parties[i] == j - i:
                        continue
                 # partidele i și j pot forma o coaliție
                     else:
                left = i-1 if i > 0 else None
                        break
                 right = j+1 if j < num_parties-1 else None
                else:
                # verificăm dacă toate partidele între i și j sunt în coaliție
                     cnt += 1
                if (left is None or parties[i] - parties[left] > 1) and (right is None or parties[right] - parties[j] > 1):
     return cnt
                     # am găsit o coaliție majoritară
                     num_majority_coalitions += 1
     return num_parties, num_majority_coalitions


def validate_output(expected, actual):
if __name__ == "__main__":
     assert expected == actual, f"Expected {expected}, but got {actual}"
    n = int(input())
    arr = list(map(int, input().split()))
    if validate_input(n, arr):
        print("Datele sunt introduse corect.")
        print(count_sequences(arr))
        print(count_coalitions(arr))
     else:
        print("Datele nu corespund restricțiilor impuse.")


if __name__ == '__main__':
    n, parties = read_input()
    num_parties, num_majority_coalitions = solve(n, parties)
    print(num_parties)
    print(num_majority_coalitions)




</syntaxhighlight>
</syntaxhighlight>
== Explicatie Rezolvare ==
== Explicatie Rezolvare ==
Funcția read_input citește datele de intrare și le returnează sub forma unei perechi (n, parties), unde n este numărul de deputați, iar parties este lista cu orientările politice ale acestora.
Funcția validate_input(n, arr) verifică dacă numărul n este între 1 și 20000 și dacă fiecare element din array-ul arr este între 1 și 30000. Dacă datele nu corespund acestor restricții, funcția returnează False, altfel returnează True.
Funcția solve primește datele de intrare și calculează numărul de partide și numărul de coaliții majoritare. Pentru a calcula numărul de partide, parcurgem lista parties și numărăm câte ori întâlnim un număr care nu este consecutiv cu ultimul număr întâlnit. Pentru a calcula numărul de coaliții majoritare, parcurgem toate perechile de partide care pot forma o coaliție (adică două partide a căror diferență este egală cu diferența dintre pozițiile lor în listă) și verificăm dacă toate partidele între ele sunt în coaliție.
 
Funcția validate_output validează rezultatul returnat de funcția solve, comparându-l cu rezultatul așteptat.
Funcția count_sequences(arr) numără cel mai lung șir crescător de elemente consecutive din array-ul arr. Inițial, variabila cnt este setată la 1, pentru că fiecare element din array poate fi considerat un șir crescător de lungime 1. Apoi, se parcurge array-ul și se verifică dacă elementul curent este mai mare decât cel anterior. Dacă da, se crește numărul de elemente din șirul crescător curent, și se actualizează max_cnt dacă valoarea lui cnt este mai mare. Dacă elementul curent este mai mic sau egal decât cel anterior, se resetează cnt la 1. La final, funcția returnează max_cnt, lungimea maximă a unui șir crescător de elemente consecutive.
În funcția main, citim datele de intrare, rezolvăm problema apelând funcția solve și afișăm rezultatul.
 
Această soluție are complexitatea O(N^2), unde N este numărul de deputați din parlament. Pentru valorile maxime ale lui N (20.000), această soluție ar
Funcția count_coalitions(arr) numără numărul de sub-șiruri neadiacente din array-ul arr care au diferența maximă între cel mai mare și cel mai mic element mai mică sau egală cu 1. Funcția parcurge fiecare pereche de elemente din array, calculează diferența dintre ele și verifică dacă aceasta este mai mare sau egală cu 2. Dacă da, atunci verifică dacă există vreun alt element între cele două care să aibă o diferență mai mică sau egală cu cea dintre cele două. Dacă există un astfel de element, atunci sub-șirul nu este valid și se trece la următoarea pereche de elemente. Dacă nu există un astfel de element, atunci sub-șirul este valid și se crește numărul de sub-șiruri găsite. La final, funcția returnează numărul de sub-șiruri valide găsite.
 
Funcția __main__ primește datele de intrare și le validează folosind funcția validate_input. Dacă datele sunt valide, afișează un mesaj de confirmare și calculează valorile cerute folosind funcțiile count_sequences și count_coalitions. Dacă datele nu sunt valide, afișează un mesaj de eroare.

Versiunea curentă din 14 mai 2023 22:42

Sursa: 2405 - politic



Cerinţa

În Țara lui Papură Vodă s-au organizat de curând primele alegeri democratice. A rezultat astfel un parlament din care fac parte deputați cu diverse doctrine politice, de stânga sau de dreapta. Acestea sunt descrise prin numere naturale nenule (orientarea politică este cu atât mai de stânga cu cât numărul este mai mic). Parlamentarii s-au asociat în partide politice în funcție de doctrina fiecăruia. Oricare doi deputați ale căror doctrine corespund unor numere consecutive fac parte din același partid. Prin urmare, partidele vor fi alcătuite din deputați ale căror doctrine sunt numere consecutive. (De exemplu, dacă parlamentul are 5 deputați, cu doctrinele 1, 2, 3, 5 şi 6, atunci înseamnă că aceștia sunt grupați în două partide: unul format din 1, 2 și 3 și altul din 5 și 6.) Un guvern trebuie să beneficieze de susținerea a mai mult de jumătate dintre parlamentari. De exemplu, dacă parlamentul este format din 7 deputați, atunci un guvern are nevoie de susținerea a cel puțin 4 deputați. Pentru a putea guverna, partidele se pot grupa in coaliţii. Regula după care se asociază este urmatoarea: două partide A şi B, A având o doctrină mai de stânga, pot face parte din aceeași coaliţie doar dacă din coaliţia respectivă fac parte toate partidele a căror doctrină este mai de dreapta decât cea a lui A şi mai de stânga decât cea a lui B. De exemplu, dacă parlamentul este alcătuit din deputaţi cu orientările politice 1, 2, 4, 5, 7 şi 8, atunci partidul format din 1 şi 2 nu se poate asocia cu partidul format din 7 şi 8 decât dacă din coaliţia respectivă face parte şi partidul format din 4 şi 5. Fiind dat parlamentul din Ţara lui Papură Vodă printr-un şir ordonat strict crescător de numere naturale nenule, se cere să se stabilească numărul de partide parlamentare şi numărul variantelor de coaliţie majoritară.


Date de intrare

Fișierul de intrare politic.in conține pe prima linie un număr natural nenul N, reprezentând numărul de deputați din parlament. Pe a doua linie se află N numere naturale nenule separate prin câte un spațiu, ordonate strict crescător, reprezentând doctrinele parlamentarilor.


Date de ieșire

Dacă datele sunt introduse corect, pe ecran se va afișa: "Datele sunt introduse corect.", fișierul de ieșire politic.out conține prima linie numărul C, reprezentând numărul de secvenţe cu elementele ordonate crescător din şirul dat, reprezentând valoarea cerută. În cazul contrar, se va afișa pe ecran: "Datele nu corespund restricțiilor impuse.".

Restricţii şi precizări

  • 0 < N ≤ 20.000
  • numerele din șir sunt mai mici sau egale cu 30.000

Exemplu 1

Intrare
politic.in
10
1 2 3 5 6 8 10 11 14 15
Ieșire
Datele sunt introduse correct.
politic.out
5
4

Exemplu 2

Intrare
politic.in
20
0 7 8 9 1 2 3 4 5
Ieșire
Datele nu corespund restricțiilor impuse.

Rezolvare

Rezolvare ver. 1

# 2405 - politic

def validate_input(n, arr):
    if n <= 0 or n > 20000:
        return False
    if any(x <= 0 or x > 30000 for x in arr):
        return False
    return True

def count_sequences(arr):
    cnt = 1
    max_cnt = 1
    for i in range(1, len(arr)):
        if arr[i] > arr[i-1]:
            cnt += 1
            if cnt > max_cnt:
                max_cnt = cnt
        else:
            cnt = 1
    return max_cnt

def count_coalitions(arr):
    cnt = 0
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            diff = abs(arr[i] - arr[j])
            if diff == 1:
                break
            else:
                for k in range(i+1, j):
                    if abs(arr[k] - arr[i]) > diff and abs(arr[k] - arr[j]) > diff:
                        continue
                    else:
                        break
                else:
                    cnt += 1
    return cnt

if __name__ == "__main__":
    n = int(input())
    arr = list(map(int, input().split()))
    if validate_input(n, arr):
        print("Datele sunt introduse corect.")
        print(count_sequences(arr))
        print(count_coalitions(arr))
    else:
        print("Datele nu corespund restricțiilor impuse.")

Explicatie Rezolvare

Funcția validate_input(n, arr) verifică dacă numărul n este între 1 și 20000 și dacă fiecare element din array-ul arr este între 1 și 30000. Dacă datele nu corespund acestor restricții, funcția returnează False, altfel returnează True.

Funcția count_sequences(arr) numără cel mai lung șir crescător de elemente consecutive din array-ul arr. Inițial, variabila cnt este setată la 1, pentru că fiecare element din array poate fi considerat un șir crescător de lungime 1. Apoi, se parcurge array-ul și se verifică dacă elementul curent este mai mare decât cel anterior. Dacă da, se crește numărul de elemente din șirul crescător curent, și se actualizează max_cnt dacă valoarea lui cnt este mai mare. Dacă elementul curent este mai mic sau egal decât cel anterior, se resetează cnt la 1. La final, funcția returnează max_cnt, lungimea maximă a unui șir crescător de elemente consecutive.

Funcția count_coalitions(arr) numără numărul de sub-șiruri neadiacente din array-ul arr care au diferența maximă între cel mai mare și cel mai mic element mai mică sau egală cu 1. Funcția parcurge fiecare pereche de elemente din array, calculează diferența dintre ele și verifică dacă aceasta este mai mare sau egală cu 2. Dacă da, atunci verifică dacă există vreun alt element între cele două care să aibă o diferență mai mică sau egală cu cea dintre cele două. Dacă există un astfel de element, atunci sub-șirul nu este valid și se trece la următoarea pereche de elemente. Dacă nu există un astfel de element, atunci sub-șirul este valid și se crește numărul de sub-șiruri găsite. La final, funcția returnează numărul de sub-șiruri valide găsite.

Funcția __main__ primește datele de intrare și le validează folosind funcția validate_input. Dacă datele sunt valide, afișează un mesaj de confirmare și calculează valorile cerute folosind funcțiile count_sequences și count_coalitions. Dacă datele nu sunt valide, afișează un mesaj de eroare.