De hecho, hay un algoritmo de tiempo lineal para esto. Solo necesita usar algunos conceptos básicos de teoría de números. Dados dos númerosnorte1 y norte2, su suma es divisible a K, solo si la suma de su resto es divisible a K. En otras palabras,
K∣ (norte1+norte2) ⟺ K ∣ ( (norte1 m o d K) + (norte2 m o d K) ) .
El segundo concepto que debe tener en cuenta es que, la suma de dos números r1≠r2 es K, solo si uno de ellos es estrictamente más pequeño que K/ 2 y el otro no es menos que K/2. En otras palabras,
r1+r2=K ⇒ r1<K/2, r2≥K/2 (r1≠r2, w.l.g. r1<r2).
El tercer concepto que debe tener en cuenta es que, si la suma de dos números r1≠r2 es K, ambos se desvían de ⌈K/2⌉−1 por cierto k≤⌈K/2⌉es decir,
r1+r2=K ⇒ ∃k≤⌈K/2⌉−1 such that r1=⌈K/2⌉−1−k, r2=⌈K/2⌉+k.
Entonces, para todos k en el tercer concepto, necesitas poner r1 o r2en el conjunto de soluciones, pero no en ambos. Se le permite poner uno de los números que son divisibles porK y si K es par, solo puede agregar un número cuyo resto es K/2.
Por lo tanto, aquí está el algoritmo.
Dado un conjunto N={n1,n2,⋯,nN}, busquemos el conjunto de soluciones S,
- Considerar R={r1=(n1 mod K),r2=(n2 mod K),⋯,rN=(nN mod K)}
- S←∅
- para k←1 a ⌈K/2⌉−1:
- Si count(R,k)≥count(R,K−k):
- añadir todo ni a Stal que ri=k
- más:
- añadir todo ni a Stal que ri=K−k
- agrega solo uno ni a S tal que ri=0// si existe
- Si K incluso:
- agrega solo uno ni a S tal que ri=K/2// si existe
- Salida S
El algoritmo es bastante largo, pero la idea es muy simple.