1811 - Aritma
Cerinţa[edit | edit source]
Shaka, regele zuluşilor, a dat ordin să se realizeze un sistem de comunicaţii bazat pe tobe (tamtam)care să acopere întreaga ţară. Pentru aceasta el a dispus instruirea celor ce vor urma să transmită mesajele. Problema intervenită este aceea că o parte din cursanţi nu pot face distincţie între sunete şi nu pot reda cu fidelitate succesiunea de sunete pe hârtie. S-a făcut următoarea convenţie de notare: un sunet lung va fi reprezentat prin +, unul scurt prin -, iar unul nedecis (receptorul nu e sigur de lungimea sunetului) prin *.
Spre finalul stagiului Shaka a mers să verifice nivelul de pregătire al cursanţilor. Pentru aceasta el a adunat n cursanţi pe care i-a pus să recepţioneze şi să noteze un mesaj format din m sunete. După transmiterea mesajului s-a constatat că mulţi dintre cursanţi au scris şiruri foarte diferite, ceea ce ducea la o alterare semnificativă a mesajului original, chiar dacă nici cel mai slab pregătit cursant nu a fost indecis la mai mult de jumătate din sunete. Supărat Shaka l-a chemat pe instructorul şef şi, ca să-l pedepsească, i-a cerut ca să determine câte mesaje distincte se pot forma din şirurile scrise de cursanţi.
Scrieţi un program care determină numărul de mesaje distincte rezultate.
Date de intrare[edit | edit source]
Fişierul aritma.in conţine pe prima sa linie numerele n şi m separate prin spaţiu, iar pe următoarele n linii şiruri de caractere de lungime m formate numai din simbolurile +, - sau *.
Date de ieșire[edit | edit source]
Pe prima linie a fişierului aritma.out se va scrie numărul de mesaje distincte.
Restricţii şi precizări[edit | edit source]
- 1 < n < 25
- 1 < m < 19
Exemplu[edit | edit source]
- aritma.in
3 3 +-* +*+ -*+
- aritma.out
5
Explicație[edit | edit source]
Mesajele rezultate sunt: +--, +-+, +++, +-+, --+, -++. Primele două mesaje sunt rezultate din prima identificare, următoarele două sunt din a doua identificare şi ultimele două din ultimul şir; numai cinci sunt distincte.
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line> def distinct_messages(strings):
def backtrack(index): if index == len(strings[0]): messages.add("".join(message)) return
# Dacă sunetul este cunoscut, îl adăugăm în mesaj if all(s[index] != '*' for s in strings): message.append(strings[0][index]) backtrack(index + 1) message.pop()
# Dacă sunetul este incert, încercăm toate posibilitățile elif any(s[index] == '*' for s in strings): for sound in ['+', '-', '*']: message.append(sound) backtrack(index + 1) message.pop()
messages = set() message = [] backtrack(0) return len(messages)
def main():
# Citim datele de intrare with open("aritma.in", "r") as fin: n, m = map(int, fin.readline().split()) strings = [fin.readline().strip() for _ in range(n)]
# Determinăm numărul de mesaje distincte result = distinct_messages(strings)
# Scriem rezultatul în fișierul de ieșire with open("aritma.out", "w") as fout: fout.write(str(result) + "\n")
if __name__ == "__main__":
main()
</syntaxhighlight>