Problemi 048
Kërkesa
Pjesëtuesi më i madh i përbashkët (PMP) i disa numrave është ai numër që i plotpjesëton të gjithë.
Na jepet një listë me N numra natyrorë dhe na lejohet të fshimë disa prej tyre (nga 0 deri në N-1, mjafton që lista të mos ngelet bosh).
Bëni një program që gjen numrin më të vogël të elementëve që duhen
fshirë, në mënyrë që PMP-ja e numrave që mbeten të jetë 1. Nëse
është e pamundur që PMP-ja të bëhet 1, programi duhet të printojë
-1
.
Referenca: https://www.codechef.com/problems/RD19
Shembull
$ cat input.txt
2
2
2 3
2
2 4
$ python3 prog.py < input.txt
0
-1
Në rastin e parë nuk është nevoja të fshimë asnjë numër sepse pmp(2,3) == 1
.
Në rastin e dytë është e pamundur që PMP të bëhet 1, pavarësisht se cilët numra fshijmë.
Zgjidhja 1
def pmp(a, b):
'''
Gjej pjesetuesin me te madh te perbashket te dy numrave te dhene.
'''
while a > 0:
a, b = b % a, a
return b
T = int(input())
for t in range(T):
input()
L = list(map(int, input().split()))
# gjej pjesetuesin me te madh te perbashket
p = L[0]
for n in L:
p = pmp(p, n)
print(0) if p==1 else print(-1)
Sqarime
Nqs një numër i plotpjesëton të gjithë numrat e një liste dhe ne heqim disa prej numrave të listës, ky numër i plotpjesëton gjithsesi numrat e mbetur të listës. Kështu që nuk ka gjasa që PMP i një liste të zvogëlohet duke fshirë disa prej elementeve të listës (vetëm mund të rritet).
Si pasojë, nqs PMP i numrave të listës është 1, atere nuk është nevoja të fshimë asnjë prej numrave të listës dhe përgjigja është 0. Përndryshe është e pamundur që PMP të bëhet 1 duke fshirë numra të listës, dhe përgjigja është -1.
Programi ynë thjesht gjen PMP e të gjithë numrave të listës dhe shikon nëse është 1 ose jo.
Zgjidhja 2
import math
for _ in range(int(input())):
input()
L = list(map(int, input().split()))
# gjej pjesetuesin me te madh te perbashket
pmp = L[0]
for n in L:
pmp = math.gcd(pmp, n)
print(0) if pmp==1 else print(-1)
Sqarime
Përdorim funksionin e gatshëm gcd()
të librarisë math
.
Provoni këto komanda në terminal:
$ python3
>>> import math
>>> help(math)
>>> dir(math)
>>> help(math.gcd)
>>> quit()
Shënim: Shtypni q për të dalë nga help()
.
Zgjidhja 3
from math import gcd
from functools import reduce
for _ in range(int(input())):
input()
L = list(map(int, input().split()))
# gjej pjesetuesin me te madh te perbashket
pmp = reduce(gcd, L)
print(0) if pmp==1 else print(-1)
Sqarime
Funksioni functools.reduce()
merr si parametër të parë emrin e një
funksioni, dhe si parametër të dytë një listë. Duke përdorur
funksionin e dhënë ai i përpunon elementët e listës 2 e nga 2, deri sa
ta reduktojë listën në një vlerë të vetme.
P.sh. reduce(gcd, [2, 3, 4, 5])
është e njëvlershme me
gcd(gcd(gcd(2, 3), 4), 5)
.
Shikoni edhe help-in:
$ python3
>>> from functools import reduce
>>> help(reduce)
[Ctrl+D]
Detyra
Cufi sapo ka marrë një lidhje interneti të re. Të dhënat e përdorimit të internetit prej tij janë si më poshtë.
Në \(T_1\) minutat e para shpejtësia e shkarkimit që ka përdorur është \(D_1\) MB në minutë, në \(T_2\) minutat e tjera është \(D_2\) MB/min, e kështu me radhë deri në \(T_N\) minutat e fundit kur shpejtësia ka qenë \(D_N\) MB/min.
Kompania e internetit i faturon 1 dollar për çdo 1 MB të shkarkuar, me përjashtim të \(K\) minutave të para, të cilat janë falas (si pjesë e ofertës).
Gjeni sasinë totale të dollarëve që duhet të paguajë Cufi për internetin e përdorur.
Referenca: https://www.codechef.com/problems/DWNLD
Shembull
$ cat input.txt
3
2 2
2 1
2 3
2 2
1 2
2 3
3 0
1 2
2 4
10 10
$ python3 prog.py < input.txt
6
3
110
Çdo rast testimi ka si rresht të parë numrat N dhe K, pastaj vijnë N rreshta me të dhënat e shkarkimit T dhe D.
Në testin e parë, 2 minutat e para janë falas, kështu që kostoja
totale është: 2*3 = 6
.
Në testin e dytë, 2 minutat e para janë falas, kështu që kostoja
totale është: 1*3 = 3
.
Në rastin e tretë, 0 minuta janë falas, kështu që kostoja totale
është: 1*2 + 2*4 + 10*10 = 110
.