Quả thực có một thuật toán thời gian tuyến tính cho việc này. Bạn chỉ cần sử dụng một số khái niệm lý thuyết số cơ bản. Với hai số và , tổng của chúng chia hết cho , chỉ khi tổng dư của họ là chia hết cho . Nói cách khác,n 2 K Kn1n2KK
K∣(n1+n2) ⟺ K∣((n1 mod K)+(n2 mod K)).
Khái niệm thứ hai mà bạn cần xem xét là, tổng của hai số là , chỉ khi một trong số chúng nhỏ hơn và số kia không nhỏ hơn . Nói cách khác, K K / 2 K / 2r1≠r2KK/2K/2
r1+r2=K ⇒ r1<K/2, r2≥K/2 (r1≠r2, w.l.g. r1<r2).
Khái niệm thứ ba mà bạn cần xem xét là, nếu tổng của hai số là , cả hai đều lệch khỏi bởi một , I E, K ⌈ K / 2 ⌉ - 1 k ≤ ⌈ K / 2 ⌉r1≠r2K⌈K/2⌉−1k≤⌈K/2⌉
r1+r2=K ⇒ ∃k≤⌈K/2⌉−1 such that r1=⌈K/2⌉−1−k, r2=⌈K/2⌉+k.
Vì vậy, đối với evey trong khái niệm thứ ba, bạn cần đặt hoặc trong bộ giải pháp, nhưng không phải cả hai. Bạn được phép đặt một trong các số thực sự chia hết cho và nếu là số chẵn, bạn chỉ có thể thêm một số mà phần còn lại của nó là .r 1 r 2 K K K / 2kr1r2KKK/2
Do đó, đây là thuật toán.
Đặt một bộ , hãy tìm bộ giải phápS ,N={n1,n2,⋯,nN}S,
- Hãy xem xétR ={ r1= ( n1 m o d K) , r2= ( n2 m o d K) , ⋯ , rN= ( nN m o d K) }
- S← ∅
- cho đến :⌈ K / 2 ⌉ - 1k ← 1⌈ K/ 2⌉-1
- nếu :c o u n t ( R , k ) ≥ c o u n t ( R , K- k )
- thêm tất cả vào , sao choS r i = knTôiSrTôi= k
- khác:
- thêm tất cả vào , sao choS r i = K - knTôiSrTôi= K- k
- chỉ thêm một vào sao cho // nếu tồn tạiS r i = 0nTôiSrTôi= 0
- nếu chẵn:K
- chỉ thêm một vào sao cho // nếu tồn tạiS r i = K / 2niSri=K/2
- Đầu raS
Thuật toán khá dài, nhưng ý tưởng rất đơn giản.