In effetti esiste un algoritmo di tempo lineare per questo. Hai solo bisogno di usare alcuni concetti di base della teoria dei numeri. Dati due numerin1 e n2, la loro somma è divisibile per K, solo se la somma del resto è divisibile per K. In altre parole,
K∣(n1+n2) ⟺ K∣((n1 mod K)+(n2 mod K)).
Il secondo concetto che devi considerare è quello, la somma di due numeri r1≠r2 è K, solo se uno di questi è strettamente più piccolo di K/2 e l'altro non è inferiore a K/2. In altre parole,
r1+r2= K ⇒ r1< K/ 2, r2≥ K/ 2( r1≠r2, wlg r1<r2) .
Il terzo concetto che devi considerare è quello, se la somma di due numeri r1≠r2 è K, entrambi si discostano ⌈ K/ 2⌉-1 da un certo k ≤ ⌈ K/ 2⌉cioè
r1+r2= K ⇒ ∃k ≤ ⌈ K/ 2⌉-1 tale che r1= ⌈ K/ 2⌉-1-k, r2= ⌈ K/ 2⌉+k.
Quindi, per evey K nel terzo concetto, è necessario inserire entrambi r1 o r2nel set di soluzioni, ma non entrambi. È consentito inserire uno dei numeri che sono effettivamente divisibili perK e se K è pari, puoi aggiungere solo un numero che sia il resto K/ 2.
Pertanto, ecco l'algoritmo.
Dato un set N= {n1,n2, ⋯ ,nN}, troviamo il set di soluzioni S,
- Prendere in considerazione R ={r1= (n1 m o d K) ,r2= (n2 m o d K) , ⋯ ,rN= (nN m o d K) }
- S←∅
- per k←1 per ⌈K/2⌉−1:
- Se count(R,k)≥count(R,K−k):
- Aggiungi tutto ni per S, tale che ri=k
- altro:
- Aggiungi tutto ni per S, tale che ri=K−k
- aggiungere solo uno ni per S tale che ri=0// se esiste
- Se K è anche:
- aggiungere solo uno ni per S tale che ri=K/2// se esiste
- Produzione S
L'algoritmo è piuttosto lungo, ma l'idea è molto semplice.