题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6627
题意:告诉你两个数组a, b,让你求方程 的解
思路: 绝对值是这个题的考点,所以需要知道如何去绝对值 由于知道了a,b数组,那么 等于0 时 x可以求出来
把所有的x求出来 之后,按x升序排序,观察
当x <= x1 时所有的所有的绝对值内的都是负数,
当x1 <= x <= x2时 x1 的绝对值是正的 剩下的都是负的
以此类推
分成n个区间来求即可
注意结果输出的时候 需要从小到大来输出
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#define ll long long
using namespace std;
const double INF = 999999999;
const int maxn = 1e6+5;
struct node {
ll a, b;
double mid;
}pos[maxn];
struct point {
ll x, y;
double xx;
}ans[maxn];
bool cmp(node a, node b) {
return a.mid < b.mid;
}
bool cmpp(point a, point b) {
return a.xx < b.xx;
}
set<pair<ll,ll > > s;
ll suma, sumb;
int main()
{
int T, n;
ll c;
scanf("%d", &T);
while(T--) {
scanf("%d%lld", &n, &c);
s.clear();
for(int i = 1; i <= n; i++) {
scanf("%lld %lld", &pos[i].a, &pos[i].b);
pos[i].mid = -1.0 * pos[i].b / pos[i].a;
}
sort(pos + 1, pos + n + 1, cmp);
suma = 0, sumb = 0;
for(int i = 1; i <= n; i++) {
suma += (-pos[i].a);
sumb += (-pos[i].b);
}
int flag = 0, cnt = 0;
for(int i = 0; i <= n; i++) {
double l, r;
i == 0 ? l = -INF : l = pos[i].mid;
i == n ? r = INF : r = pos[i+1].mid;
ll y = suma;
ll x = c - sumb;
double ss = 1.0 * x / y;
if(l <= ss && ss <= r) {
ll g = __gcd(abs(x), abs(y));
if(x * y < 0) {
x = -abs(x) / g;
y = abs(y) / g;
}
else x = abs(x) / g, y = abs(y) / g;
s.insert(make_pair(x, y));
}
if(i == n) break;
suma += 2 * pos[i+1].a;
sumb += 2 * pos[i+1].b;
if(y == 0 && x == 0) {
flag = 1;
break;
}
}
if(flag) {
printf("-1\n");
}
else {
cnt = s.size();
printf("%d", cnt);
if(cnt) {
int len = 0;
set<pair<ll,ll> > ::iterator it;
for(it = s.begin(); it != s.end(); ++it) {
ans[len].x = it->first;
ans[len].y = it->second;
ans[len].xx = 1.0 * ans[len].x / ans[len].y;
len++;
}
sort(ans, ans + len, cmpp);
for(int i = 0; i < len; i++){
printf(" %lld/%lld",ans[i].x, ans[i].y);
}
}
printf("\n");
}
}
return 0;
}