Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Phân số duy nhất trong C++


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, ],]