Cho danh sách phân số, mỗi phân số gồm [tử số, mẫu số]. Cần tạo danh sách mới thỏa mãn:
- Rút gọn phân số về dạng tối giản (ví dụ: 20/14 → 10/7).
- Loại bỏ các phân số trùng lặp sau khi rút gọn.
- Sắp xếp tăng dần theo giá trị thực của phân số.
- Nếu âm, dấu
-nằm ở tử số.
Ví dụ: {{16,8},{4,2},{7,3},{14,6},{20,4},{-6,12}} → [[-1,2],[2,1],[7,3],[5,1]].
Các bước giải quyết:
- Dùng
setđể lưu phân số đã rút gọn (tự loại trùng). - Duyệt từng phân số, chia tử và mẫu cho GCD của chúng.
- Sắp xếp theo giá trị thực
(double)tử/mẫu. - Trả về kết quả.
Ví dụ
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<vector<int>> v) {
cout << "[";
for (int i = 0; i < v.size(); i++) {
cout << "[";
for (int j = 0; j < v[i].size(); j++)
cout << v[i][j] << ", ";
cout << "],";
}
cout << "]" << endl;
}
class Solution {
public:
static bool cmp(vector<int>& a, vector<int>& b) {
double aa = (double)a[0] / a[1];
double bb = (double)b[0] / b[1];
return aa < bb;
}
vector<vector<int>> solve(vector<vector<int>>& v) {
set<vector<int>> s;
int n = v.size();
vector<vector<int>> r;
for (int i = 0; i < n; i++) {
int c = __gcd(abs(v[i][0]), abs(v[i][1]));
v[i][0] /= c;
v[i][1] /= c;
r.push_back({v[i][0], v[i][1]});
}
sort(r.begin(), r.end(), cmp);
vector<vector<int>> ret;
for (int i = 0; i < r.size(); i++) {
if (!ret.empty() && ret.back() == r[i]) continue;
ret.push_back(r[i]);
}
return ret;
}
};
int main() {
vector<vector<int>> v = {{16,8},{4,2},{7,3},{14,6},{20,4},{-6,12}};
Solution ob;
print_vector(ob.solve(v));
}
Đầu vào
{{16,8},{4,2},{7,3},{14,6},{20,4},{-6,12}}
Đầu ra
[[-1, 2, ],[2, 1, ],[7, 3, ],[5, 1, ],]