Memang ada algoritma waktu linear untuk ini. Anda hanya perlu menggunakan beberapa konsep teori bilangan dasar. Mengingat dua nomor dan , jumlah mereka adalah dibagi ke , hanya jika jumlah sisa mereka dibagi ke . Dengan kata lain,n1n2KK
K∣(n1+n2) ⟺ K∣((n1 mod K)+(n2 mod K)).
Konsep kedua yang perlu Anda pertimbangkan adalah bahwa, jumlah dua angka adalah , hanya jika salah satu dari mereka benar-benar lebih kecil dari dan yang lainnya tidak kurang dari . Dengan kata lain,r1≠r2KK/2K/2
r1+r2=K ⇒ r1<K/2, r2≥K/2 (r1≠r2, w.l.g. r1<r2).
Konsep ketiga yang perlu Anda pertimbangkan adalah bahwa, jika jumlah dua angka adalah , keduanya menyimpang dari oleh yaitur1≠r2K⌈K/2⌉−1k≤⌈K/2⌉
r1+r2=K ⇒ ∃k≤⌈K/2⌉−1 such that r1=⌈K/2⌉−1−k, r2=⌈K/2⌉+k.
Jadi, untuk setiap dalam konsep ketiga, Anda perlu memasukkan atau dalam set solusi, tetapi tidak keduanya. Anda diizinkan untuk meletakkan salah satu angka yang sebenarnya dapat dibagi oleh dan jika genap, Anda dapat menambahkan hanya satu angka yang sisanya adalah .kr1r2KKK/2
Karena itu, berikut adalah algoritmenya.
Diberikan set , mari cari solusi setN={n1,n2,⋯,nN}S,
- PertimbangkanR={r1=(n1 mod K),r2=(n2 mod K),⋯,rN=(nN mod K)}
- S←∅
- untuk hingga :k←1⌈K/2⌉−1
- jika :count(R,k)≥count(R,K−k)
- tambahkan semua ke , sedemikian rupa sehingganiSri=k
- lainnya:
- tambahkan semua ke , sedemikian rupa sehingganiSri=K−k
- tambahkan hanya satu ke sedemikian rupa sehingga // jika adaniSri=0
- jika genap:K
- tambahkan hanya satu ke sedemikian rupa sehingga // jika adaniSri=K/2
- KeluaranS
Algoritma ini cukup panjang, tetapi idenya sangat sederhana.