杭电多校第5场1004(HDU 6627)equation
题意:给你若干个a,b让你解决一条公式,解方程。
解法:每个绝对值内部都有一个零点,对这些0点排序,所有绝对值的情况只剩下N+1种。从全为负的,到第一个绝对值内部为正,然后第一第二个为正,一直推到全为正的,每次解方程然后判断值是不是在这个区间内。注意判断-1和0。(WA到绝望,赛后对拍数据发现过了98%的样例,只是特判-1的情况写错了,真想打爆自己。。)我的程序在判断区间的时候,对于区间边界也都涵盖进来了,这样可能有重复数据,要进行去重。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mx = 2e5 + 7;
int a[mx], b[mx];
ll ans[mx][2];
ll an[mx][2];
struct node {
double x;
int p;
}ab[mx];
long long prea[mx],preb[mx];
bool cmp(node a,node b){
return a.x < b.x;
}
long long gcd(long long a, long long b) {
return b ? gcd(b, a % b) : a;
}
int qc(int pos) {
int len=0;
for (int i = 1; i <= pos; i++)
{
if( (1.0*ans[i][0]/ans[i][1])== (1.0 * ans[i+1][0] / ans[1+i][1])){
len++;
an[len][0] = ans[i][0];
an[len][1] = ans[i][1];
i++;
}
else {
len++;
an[len][0] = ans[i][0];
an[len][1] = ans[i][1];
}
}
return len;
}
int main() {
//#ifdef ONLINE_JUDGE
//#else
// freopen("std.in", "r", stdin);
//#endif
int t;
cin >> t;
while (t--) {
int n;
long long c;
scanf("%d%lld", &n, &c);
for (int i = 1; i <= n; i++) {
int x, y;
scanf("%d%d", &x, &y);
a[i] = x, b[i] = y;
ab[i].x = -1.0 * y / x;
ab[i].p = i;
}
sort(ab + 1, ab + n + 1,cmp);
prea[0] = preb[0] = 0;
for (int i = 1; i <= n; i++)
prea[i] = prea[i - 1] + a[ab[i].p], preb[i] = preb[i - 1] + b[ab[i].p];
int pos = 0;
int f = 1;
{
double A = -prea[n];
double B = -preb[n];
if (A == 0 && B == c) {
printf("-1\n");
continue;
}
double x = 1.0 * (c - B) / A;
if (x <= ab[1].x) {
ll g = gcd(c - B, A);
pos++;
ans[pos][0] = (c - B) / g;
ans[pos][1] = (A) / g;
}
}
for (int i = 1; i <= n-1; i++) {
double A = 2 * prea[i] - prea[n];
double B = 2 * preb[i] - preb[n];
if (A == 0&&B==c) {
printf("-1\n");
f = 0;
break;
}
double x = 1.0 * (c - B) / A;
if (x >= ab[i].x && x <= ab[i + 1].x) {
ll g = gcd(c - B, A);
pos++;
ans[pos][0] = (c - B) / g;
ans[pos][1] = (A) / g;
}
}
{
double A = prea[n];
double B = preb[n];
if (A == 0 && B == c) {
printf("-1\n");
continue;
}
double x = 1.0 * (c - B) / A;
if (x >= ab[n].x) {
ll g = gcd(c - B, A);
pos++;
ans[pos][0] = (c - B) / g;
ans[pos][1] = (A) / g;
}
}
if (f) {
if (pos == 0) {
printf("%d\n", pos);
continue;
}
else {
pos = qc(pos);
printf("%d ", pos);
for (int i = 1; i <= pos ; i++) {
if (an[i][0] == 0)
printf("0/1");
else {
if (an[i][0] * an[i][1] < 0)
printf("-%lld/%lld", abs(an[i][0]), abs(an[i][1]));
else
printf("%lld/%lld", abs(an[i][0]), abs(an[i][1]));
}
if (i != pos)
printf(" ");
}
}
}
else
continue;
printf("\n");
}
return 0;
}