Cho mảng A, B cùng kích thước n. Sắp xếp lại B sao cho dãy C[i] = (A[i] + B[i]) % n nhỏ nhất theo thứ tự từ điển (lexicographically).
Ví dụ
A = {1,2,3,2}, B = {4,3,2,2}
Output: [0, 0, 1, 2]
Thuật toán tham lam + Multiset
- Duyệt i từ 0 đến n-1.
- Với A[i], cần chọn x ∈ B còn lại sao cho
(A[i] + x) % nnhỏ nhất. - Mục tiêu:
(A[i] + x) % n= 0 nếu có thể → cầnx ≡ (n - A[i]) % n. - Dùng
multiset+lower_boundtìm x ≥ target, nếu không có lấy phần tử nhỏ nhất.
Triển khai C++
#include <bits/stdc++.h>
using namespace std;
vector<int> solve(vector<int>& a, vector<int>& b) {
int n = a.size();
multiset<int> ms(b.begin(), b.end());
vector<int> res;
for (int x : a) {
int need = (n - x) % n;
auto it = ms.lower_bound(need);
if (it == ms.end()) it = ms.begin(); // wrap around
int val = *it;
res.push_back((x + val) % n);
ms.erase(it);
}
return res;
}
int main() {
vector<int> a = {1,2,3,2};
vector<int> b = {4,3,2,2};
auto res = solve(a, b);
for (int x : res) cout << x << " ";
return 0;
}
Kết quả
0 0 1 2
Độ phức tạp: O(n log n) do multiset.