HDU6627 equation (枚舉+數學)

HDU6627 equation (枚舉+數學)

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6627

我的博客:https://acmerszq.cn

題意:

​ 求解方程,(i=1naix+bi)=C(\sum_{i=1}^n {|a_i*x+b_i|}) = C,求滿足所有條件的x。無限個解的時候輸出-1,若有x = 0時,輸出 0/10/1

思路:

​ 先把所有的aia_i加起來,所有的bib_i加起來,取相反數。再O(n)O(n)的枚舉求n+1n+1個區間裏的答案。

​ 比賽一直WA到結束,都絕望了,然後發現,原來只是自己在答案爲00時沒有判斷是否在區間內,我人沒了,orz。。。

AC代碼:

#include <bits/stdc++.h>
using namespace std;
const int SIZE = 1e5+5;
const int INF = 0x3f3f3f3f;
struct Node {
    int a, b;
    int id;
    double aDb;
    Node() : a(0), b(0) {}
} arr[SIZE];
int xNum, num;
bool cmp(const Node& a, const Node& b) {
    if(a.aDb != b.aDb) return a.aDb < b.aDb;
    else return a.id < b.id;
}
struct A {
    int a, b;
    int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
    void get() {
        int num = gcd(a, b);
        a /= num;
        b /= num;
    }
    inline bool operator < (const A &tt) const {
        double t1 = (double)a/b;
        double t2 = (double)tt.a/tt.b;
        return t1 < t2;
    }
};
set<A> ans;
double l, r;
int main() {
    // freopen("RAW/in", "r", stdin);
    // freopen("RAW/out", "w", stdout);
    int T;
    scanf("%d", &T);
    while(T--) {
        ans.clear();
        l = r = -INF;
        int n, c;
        xNum = num = 0;
        scanf("%d%d", &n, &c);
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &arr[i].a, &arr[i].b);
            arr[i].id = i;
            xNum += (-arr[i].a);
            num += (-arr[i].b);
            arr[i].aDb = -((double)arr[i].b/arr[i].a);
        }
        sort(arr, arr + n, cmp);
        bool flag = false;
        for(int i = 0; i <= n; i++) {
            if(i < n) r = arr[i].aDb;
            else r = INF;
            int a = c-num;
            if(xNum == 0 && a == 0) {
                flag = true;
                break;
            }
            A temp;
            if(a == 0) {
                temp.a = 0;
                temp.b = 1;
                if(0 >= l && 0 <= r) ans.insert(temp); 
            } else {
                double tt = (double)a/xNum;
                if(tt >= l && tt <= r) {
                    temp.a = a;
                    temp.b = xNum;
                    temp.get();
                    ans.insert(temp);
                }
            }
            num += 2*arr[i].b;
            xNum += 2*arr[i].a;
            l = arr[i].aDb;
        }
        if(flag) printf("-1");
        else {
            int len = ans.size();
            printf("%d", len);
            for(set<A>::iterator it = ans.begin(); it != ans.end(); it++) {
                if(1.0*(*it).a/(*it).b < 0) printf(" -");
                else printf(" ");
                printf("%d/%d", abs((*it).a), abs((*it).b));
            }
        }
        printf("\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章