2387 - Mosia 1: Diferență între versiuni

De la Universitas MediaWiki
(Pagină nouă: Păcală a primit, aşa cum era învoiala, un petec de teren de pe moşia boierului. Terenul este împrejmuit complet cu segmente drepte de gard ce se sprijină la ambele capete de câte un par zdravăn. La o nouă prinsoare, Păcală iese iar in câştig şi primeşte dreptul să strămute nişte pari, unul câte unul, cum i-o fi voia, astfel încât să-şi extindă suprafaţa de teren. Dar învoiala prevede că fiecare par poate fi mutat în orice direcţie, dar nu pe o di...)
 
Fără descriere a modificării
 
Linia 1: Linia 1:
Păcală a primit, aşa cum era învoiala, un petec de teren de pe moşia boierului. Terenul este împrejmuit complet cu segmente drepte de gard ce se sprijină la ambele capete de câte un par zdravăn. La o nouă prinsoare, Păcală iese iar in câştig şi primeşte dreptul să strămute nişte pari, unul câte unul, cum i-o fi voia, astfel încât să-şi extindă suprafaţa de teren. Dar învoiala prevede că fiecare par poate fi mutat în orice direcţie, dar nu pe o distanţă mai mare decât o valoare dată (scrisă pe fiecare par) şi fiecare segment de gard, fiind cam şubred, poate fi rotit şi prelungit de la un singur capăt, celălalt rămânând nemişcat.
Păcală a primit, aşa cum era învoiala, un petec de teren de pe moşia boierului. Terenul este împrejmuit complet cu segmente drepte de gard ce se sprijină la ambele capete de câte un par zdravăn. La o nouă prinsoare, Păcală iese iar in câştig şi primeşte dreptul să strămute nişte pari, unul câte unul, cum i-o fi voia, astfel încât să-şi extindă suprafaţa de teren. Dar învoiala prevede că fiecare par poate fi mutat în orice direcţie, dar nu pe o distanţă mai mare decât o valoare dată (scrisă pe fiecare par) şi fiecare segment de gard, fiind cam şubred, poate fi rotit şi prelungit de la un singur capăt, celălalt rămânând nemişcat.
== Cerința ==
 
Cunoscând poziţiile iniţiale ale parilor şi valoarea înscrisă pe fiecare par, se cere suprafaţa maximă cu care poate să-şi extindă Păcală proprietatea. Se ştie că parii sunt daţi într-o ordine oarecare, poziţiile lor iniţiale sunt date prin numere întregi de cel mult 3 cifre, distanțele pe care fiecare par poate fi deplasat sunt numere naturale strict pozitive şi figura formată de terenul iniţial este un poligon neconcav.
= Cerința =
== Date de intrare ==
Cunoscând poziţiile iniţiale ale parilor şi valoarea înscrisă pe fiecare par, se cere suprafaţa maximă cu care poate să-şi extindă Păcală proprietatea. Se ştie că parii sunt daţi într-o ordine oarecare, poziţiile lor iniţiale sunt date prin numere întregi de cel mult <code>3</code> cifre, distanțele pe care fiecare par poate fi deplasat sunt numere naturale strict pozitive şi figura formată de terenul iniţial este un poligon neconcav.
Fișierul de intrare mosia1in.txt conţine n+1 linii cu următoarele valori:
 
<br>
= Date de intrare =
n – numărul de pari
Fișierul de intrare <code>mosia1IN.txt</code> conţine <code>n+1</code> linii cu următoarele valori:
<br>
 
x[1] y[1] d[1] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul 1
<code>n</code> – numărul de pari
<br>
 
x[2] y[2] d[2] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul 2
<code>x[1] y[1] d[1]</code> – coordonatele iniţiale şi distanţa pe care poate fi mutat parul <code>1</code>
<br>
 
<code>x[2] y[2] d[2]</code> – coordonatele iniţiale şi distanţa pe care poate fi mutat parul <code>2</code>
 
. . .
. . .
<br>
 
x[n] y[n] d[n] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul n
<code>x[n] y[n] d[n]</code> – coordonatele iniţiale şi distanţa pe care poate fi mutat parul <code>n</code>
== Date de ieșire ==  
 
Fișierul de ieșire mosia1out.txt se scrie un număr real cu 4 zecimale ce reprezintă suprafața maximă cu care se poate mări moșia.
= Date de ieșire =
== Restricții și precizări ==
Fișierul de ieșire <code>mosia1OUT.txt</code> se scrie un număr real cu <code>4</code> zecimale ce reprezintă suprafața maximă cu care se poate mări moșia. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".
*3 < N ≤ 200 număr natural
 
*–1000 < x[i], y[i] < 1000 numere întregi
= Restricții și precizări =
*0 < d[i] ≤ 20 numere întregi
 
*poligonul neconcav se defineşte ca un poligon convex cu unele vârfuri coliniare
* <code>3 < N ≤ 200</code> număr natural
*poziţiile parilor sunt date într-o ordine oarecare
* <code>–1000 < x[i], y[i] < 1000</code> numere întregi
*poligonul obţinut după mutarea parilor poate fi concav
* <code>0 < d[i] ≤ 20</code> numere întregi
*poziţiile finale ale parilor nu sunt in mod obligatoriu numere naturale
* poligonul neconcav se defineşte ca un poligon convex cu unele vârfuri coliniare
== Exemplul 1 ==
* poziţiile parilor sunt date într-o ordine oarecare
; mosia1in.txt
* poligonul obţinut după mutarea parilor poate fi concav
: 4
* poziţiile finale ale parilor nu sunt in mod obligatoriu numere naturale
: -3 0 2
 
: 3 0 3
= Exemplul 1: =
: 0 6 2
<code>mosia1IN.txt</code>
: 0 -6 6
4
; mosia1out.txt
-3 0 2
: 30.0000
3 0 3
<br>
0 6 2
== Exemplul 2 ==
0 -6 6
; mosia1in.txt
<code>mosia1OUT.txt</code>
: 5
30.0000
: 1 1 2
 
: 3 1 3
=== Explicație ===
: 4 3 4
Prin mutarea parilor <code>1</code> si <code>2</code> cu câte <code>2</code> și respectiv <code>3</code> unități, se obține un teren având suprafaţa cu <code>30</code> de unităţi mai mare decât terenul iniţial.
: 2 4 2
 
: -2 3 5
== Exemplul 2: ==
; mosia1out.txt
<code>mosia1IN.txt</code>
: 13.5000
2
<br>
-3 0 2
3 0 3
0 6 2
0 -6 6
<code>mosia1OUT.txt</code>
Datele nu corespund restrictiilor impuse
 
== Rezolvare ==  
== Rezolvare ==  
<syntaxhighlight lang="python" line>
<syntaxhighlight lang="python" line="1">
#2387 - Mosia 1
import math
def check_restrictions(N, points):
 
    if not (3 < N <= 200):
m = 10000000.0
        return False


     if not all(-1000 < point[0] < 1000 and -1000 < point[1] < 1000 and 0 < point[2] <= 20 for point in points):
def cit():
        return False
     global n, p
    p = []
    with open("mosia1IN.txt", "r") as f:
        n = int(f.readline().strip())
        for _ in range(n):
            x, y, d = map(int, f.readline().strip().split())
            p.append({'x': x, 'y': y, 'd': d})


     return True
def poz(pp, u):
    i = pp
    j = u
    i0 = 0
    j0 = -1
    while i < j:
        if p[i]['si'] - p[j]['si'] > 1/m or (abs(p[i]['si'] - p[j]['si']) < 1/m and p[i]['di'] - p[j]['di'] > 1/m and p[i]['si'] < 0) or (abs(p[i]['si'] - p[j]['si']) < 1/m and p[j]['di'] - p[i]['di'] > 1/m and p[i]['si'] > 0):
            p[i], p[j] = p[j], p[i]
            aux1 = -i0
            i0 = -j0
            j0 = aux1
        i += i0
        j += j0
     return i


def area_of_polygon(x, y):
def quick(p, u):
     n = len(x)
     if p < u:
    area = 0
        k = poz(p, u)
    for i in range(n):
         quick(p, k - 1)
         j = (i + 1) % n
         quick(k + 1, u)
         area += x[i] * y[j] - x[j] * y[i]
    return abs(area) / 2.0


def main():
def preprocesare():
     # Citirea datelor de intrare
     global p
     try:
     i0 = 0
         with open("mosia1in.txt", "r") as file:
    for i in range(1, n):
             N = int(file.readline())
         if p[i]['x'] < p[i0]['x'] or (p[i]['x'] == p[i0]['x'] and p[i]['y'] < p[i0]['y']):
            points = [list(map(int, file.readline().split())) for _ in range(N)]
             i0 = i
     except FileNotFoundError:
    p[0], p[i0] = p[i0], p[0]
        print("false")
    for i in range(1, n):
        return
        p[i]['di'] = math.sqrt((p[i]['x'] - p[0]['x'])**2 + (p[i]['y'] - p[0]['y'])**2)
        p[i]['si'] = (p[i]['y'] - p[0]['y']) / p[i]['di']
     quick(1, n-1)
    p = [p[-1]] + p + [p[0]]


    # Verificarea restricțiilor
def arie(i):
     if not check_restrictions(N, points):
     return p[i]['d'] * math.sqrt((p[i-1]['x'] - p[i+1]['x'])**2 + (p[i-1]['y'] - p[i+1]['y'])**2) / 2.0
        print("false")
        return


     # Inițializare variabile
def pd():
     x = [point[0] for point in points]
     global sol
     y = [point[1] for point in points]
     s0 = [0] * (n + 2)
     initial_area = area_of_polygon(x, y)
    s1 = [0] * (n + 2)
    for i in range(1, n):
        s0[i+1] = max(s0[i], s1[i])
        s1[i+1] = s0[i] + arie(i + 1)
    sol = max(s0[n], s1[n])
    s0[0] = 0
     s1[0] = arie(1)
    s0[1] = s1[1] = s1[0]
    for i in range(2, n):
        s0[i] = max(s0[i-1], s1[i-1])
        s1[i] = s0[i-1] + arie(i + 1)
     sol = max(sol, s0[n-1])


    # Procesarea mutărilor
def verifica_restrictii():
     for i in range(N):
     if not (3 < n <= 200):
         for j in range(1, points[i][2] + 1):
         return False
            x[i] += 1
    for punct in p:
            area = area_of_polygon(x, y)
        if not (-1000 < punct['x'] < 1000 and -1000 < punct['y'] < 1000 and 0 < punct['d'] <= 20):
             if area > initial_area:
             return False
                initial_area = area
    return True


     # Afișarea rezultatului
def main():
     with open("mosia1out.txt", "w") as file_out:
    global sol
         file_out.write(f"{initial_area:.4f}\n")
    cit()
    if not verifica_restrictii():
        with open("mosia1OUT.txt", "w") as f:
            f.write("Datele nu corespund restrictiilor impuse")
        return
    preprocesare()
     pd()
     with open("mosia1OUT.txt", "w") as f:
         f.write(f"{sol:.4f}")


if __name__ == "__main__":
if __name__ == "__main__":
Linia 101: Linia 145:


</syntaxhighlight>
</syntaxhighlight>
== Explicatie ==
Prin mutarea parilor 1 si 2 cu câte 2 și respectiv 3 unități, se obține un teren având suprafaţa cu 30 de unităţi mai mare decât terenul iniţial.

Versiunea curentă din 18 mai 2024 14:49

Păcală a primit, aşa cum era învoiala, un petec de teren de pe moşia boierului. Terenul este împrejmuit complet cu segmente drepte de gard ce se sprijină la ambele capete de câte un par zdravăn. La o nouă prinsoare, Păcală iese iar in câştig şi primeşte dreptul să strămute nişte pari, unul câte unul, cum i-o fi voia, astfel încât să-şi extindă suprafaţa de teren. Dar învoiala prevede că fiecare par poate fi mutat în orice direcţie, dar nu pe o distanţă mai mare decât o valoare dată (scrisă pe fiecare par) şi fiecare segment de gard, fiind cam şubred, poate fi rotit şi prelungit de la un singur capăt, celălalt rămânând nemişcat.

Cerința

Cunoscând poziţiile iniţiale ale parilor şi valoarea înscrisă pe fiecare par, se cere suprafaţa maximă cu care poate să-şi extindă Păcală proprietatea. Se ştie că parii sunt daţi într-o ordine oarecare, poziţiile lor iniţiale sunt date prin numere întregi de cel mult 3 cifre, distanțele pe care fiecare par poate fi deplasat sunt numere naturale strict pozitive şi figura formată de terenul iniţial este un poligon neconcav.

Date de intrare

Fișierul de intrare mosia1IN.txt conţine n+1 linii cu următoarele valori:

n – numărul de pari

x[1] y[1] d[1] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul 1

x[2] y[2] d[2] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul 2

. . .

x[n] y[n] d[n] – coordonatele iniţiale şi distanţa pe care poate fi mutat parul n

Date de ieșire

Fișierul de ieșire mosia1OUT.txt se scrie un număr real cu 4 zecimale ce reprezintă suprafața maximă cu care se poate mări moșia. În cazul în care restricțiile nu sunt îndeplinite, se va afișa mesajul "Datele nu corespund restrictiilor impuse".

Restricții și precizări

  • 3 < N ≤ 200 număr natural
  • –1000 < x[i], y[i] < 1000 numere întregi
  • 0 < d[i] ≤ 20 numere întregi
  • poligonul neconcav se defineşte ca un poligon convex cu unele vârfuri coliniare
  • poziţiile parilor sunt date într-o ordine oarecare
  • poligonul obţinut după mutarea parilor poate fi concav
  • poziţiile finale ale parilor nu sunt in mod obligatoriu numere naturale

Exemplul 1:

mosia1IN.txt

4
-3 0 2
3 0 3
0 6 2
0 -6 6

mosia1OUT.txt

30.0000

Explicație

Prin mutarea parilor 1 si 2 cu câte 2 și respectiv 3 unități, se obține un teren având suprafaţa cu 30 de unităţi mai mare decât terenul iniţial.

Exemplul 2:

mosia1IN.txt

2
-3 0 2
3 0 3
0 6 2
0 -6 6

mosia1OUT.txt

Datele nu corespund restrictiilor impuse

Rezolvare

import math

m = 10000000.0

def cit():
    global n, p
    p = []
    with open("mosia1IN.txt", "r") as f:
        n = int(f.readline().strip())
        for _ in range(n):
            x, y, d = map(int, f.readline().strip().split())
            p.append({'x': x, 'y': y, 'd': d})

def poz(pp, u):
    i = pp
    j = u
    i0 = 0
    j0 = -1
    while i < j:
        if p[i]['si'] - p[j]['si'] > 1/m or (abs(p[i]['si'] - p[j]['si']) < 1/m and p[i]['di'] - p[j]['di'] > 1/m and p[i]['si'] < 0) or (abs(p[i]['si'] - p[j]['si']) < 1/m and p[j]['di'] - p[i]['di'] > 1/m and p[i]['si'] > 0):
            p[i], p[j] = p[j], p[i]
            aux1 = -i0
            i0 = -j0
            j0 = aux1
        i += i0
        j += j0
    return i

def quick(p, u):
    if p < u:
        k = poz(p, u)
        quick(p, k - 1)
        quick(k + 1, u)

def preprocesare():
    global p
    i0 = 0
    for i in range(1, n):
        if p[i]['x'] < p[i0]['x'] or (p[i]['x'] == p[i0]['x'] and p[i]['y'] < p[i0]['y']):
            i0 = i
    p[0], p[i0] = p[i0], p[0]
    for i in range(1, n):
        p[i]['di'] = math.sqrt((p[i]['x'] - p[0]['x'])**2 + (p[i]['y'] - p[0]['y'])**2)
        p[i]['si'] = (p[i]['y'] - p[0]['y']) / p[i]['di']
    quick(1, n-1)
    p = [p[-1]] + p + [p[0]]

def arie(i):
    return p[i]['d'] * math.sqrt((p[i-1]['x'] - p[i+1]['x'])**2 + (p[i-1]['y'] - p[i+1]['y'])**2) / 2.0

def pd():
    global sol
    s0 = [0] * (n + 2)
    s1 = [0] * (n + 2)
    for i in range(1, n):
        s0[i+1] = max(s0[i], s1[i])
        s1[i+1] = s0[i] + arie(i + 1)
    sol = max(s0[n], s1[n])
    s0[0] = 0
    s1[0] = arie(1)
    s0[1] = s1[1] = s1[0]
    for i in range(2, n):
        s0[i] = max(s0[i-1], s1[i-1])
        s1[i] = s0[i-1] + arie(i + 1)
    sol = max(sol, s0[n-1])

def verifica_restrictii():
    if not (3 < n <= 200):
        return False
    for punct in p:
        if not (-1000 < punct['x'] < 1000 and -1000 < punct['y'] < 1000 and 0 < punct['d'] <= 20):
            return False
    return True

def main():
    global sol
    cit()
    if not verifica_restrictii():
        with open("mosia1OUT.txt", "w") as f:
            f.write("Datele nu corespund restrictiilor impuse")
        return
    preprocesare()
    pd()
    with open("mosia1OUT.txt", "w") as f:
        f.write(f"{sol:.4f}")

if __name__ == "__main__":
    main()