F Fraction Construction Problem

题意:

给两个数a,b求另外四个数c,d,e,f满足

  1. c d − e f = a b \frac{c}{d} - \frac{e}{f} = \frac{a}{b} dcfe=ba
  2. d < b and f < b
  3. 1 ≤ c , e ≤ 4 × 1 0 12 1≤c,e≤4×10^{12} 1c,e4×1012
    如果不存在就输出-1 -1 -1 -1
思路:

看了题解之后来写一下思路,当时做一个笔记。

这题的关键点在于第二个条件,如果没有第二个条件,这就是一道非常简单的水题因为直接构造 a + k b − k b \frac{a + k}{b} - \frac{k}{b} ba+kbk(这不是乱杀么 )。

但是有了条件二就无法这样构造,条件二似乎在提示我们, d ∗ f d * f df一定要是 b b b的整数倍,而且 d d d f f f每个都一定要含有 b b b的非1因子,否则无法满足条件二。

那么很自然就会想到质数,当 b b b为质数时上述条件似乎就无法满足了,但是如果分子是质数倍数的话不就又可以直接构造了么?

  1. 此时就可以自然地想到,假设分子分母不互质,那么毕竟约分后分母小于原分母,那么约分后的分数就可以随便构造了
    比如:
    约分后是 u n \frac{u}{n} nu那么就可以构造 u + 1 n − 1 n \frac{u + 1}{n} - \frac{1}{n} nu+1n1(真就乱杀呗 )
  2. 那么当分子和分母互质时呢,此时把式子进行通分得 c f − e d d f = a b \frac{cf -ed}{df} = \frac{a}{b} dfcfed=ba,根据上面的条件 d d d f f f每个都一定要含有 b b b的非1因子,若 d d d f f f不互质,那么 c f − e d d f = a b \frac{cf -ed}{df} = \frac{a}{b} dfcfed=ba就会约分,那么 d f df df一定到达不了 b b b,所以对于存在的质因子数等于1的b一定无解
  3. d d d f f f互质时 d ∗ f = b d*f = b df=b所以只需要求出 c c c e e e满足 c f − e d = a cf-ed=a cfed=a这明显就是exgcd的内容了
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define pb push_back
#define eps 1e-8
#define endl '\n'
using namespace std;
const ll maxn = 2e6 + 5;

ll t,a,b,c,d,e,f,cb[maxn];
bool vis[maxn];

ll exgcd(ll a,ll b, ll &x,ll &y){
    if(!b){
        x = 1,y = 0;
        return a;
    }else{
        ll d = exgcd(b,a % b,y,x);
        y -= a / b * x;
        return d;
    }
}

void Sz(){
    for(int i = 2; i <= maxn; i++){
        if(!vis[i]){
            vis[i] = 1;
            for(int j = i + i; j <= maxn; j += i){
                vis[j] = 1;
                if(!cb[j]){
                    ll k = i;
                    while(!(j % (k * i))) k *= i;
                    if(k < j)cb[j] = k;
                }
            }
        }
    }
}

void solve(){
    ll x,y,d = __gcd(a,b);
    if(d != 1)
        printf("%lld %lld %lld %lld\n",a / d + 1,b / d,1ll,b / d);
    else{
        if(!cb[b])printf("-1 -1 -1 -1\n");
        else{
            d = cb[b],f = b / d;
            exgcd(d,f,x,y);
            if(x > 0)
                printf("%lld %lld %lld %lld\n",x * a,f,-y * a,d);
            else
                printf("%lld %lld %lld %lld\n",y * a,d,-x * a,f);
        }
    }
}

int main(){
    Sz();
    scanf("%lld",&t);
    while(t--){
        scanf("%lld %lld",&a,&b);
        solve();
    }
    return 0;
}


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 C++ 分数类 `fraction` 的实现,它包含了分数的四则运算和比较运算。 ```cpp #include <iostream> using namespace std; class fraction { private: int num; // 分子 int den; // 分母 public: fraction(int n = 0, int d = 1) { if (d == 0) { cout << "分母不能为0!" << endl; exit(1); } if (d < 0) { n = -n; d = -d; } num = n; den = d; reduce(); } int getNum() const { return num; } int getDen() const { return den; } fraction operator-() const { return fraction(-num, den); } friend fraction operator+(const fraction& f1, const fraction& f2); friend fraction operator-(const fraction& f1, const fraction& f2); friend fraction operator*(const fraction& f1, const fraction& f2); friend fraction operator/(const fraction& f1, const fraction& f2); friend bool operator==(const fraction& f1, const fraction& f2); friend bool operator!=(const fraction& f1, const fraction& f2); friend bool operator<(const fraction& f1, const fraction& f2); friend bool operator>(const fraction& f1, const fraction& f2); friend bool operator<=(const fraction& f1, const fraction& f2); friend bool operator>=(const fraction& f1, const fraction& f2); friend istream& operator>>(istream& in, fraction& f); friend ostream& operator<<(ostream& out, const fraction& f); private: void reduce() { int gcd = getGCD(num, den); num /= gcd; den /= gcd; } int getGCD(int a, int b) { if (b == 0) return a; return getGCD(b, a % b); } }; fraction operator+(const fraction& f1, const fraction& f2) { return fraction(f1.getNum() * f2.getDen() + f2.getNum() * f1.getDen(), f1.getDen() * f2.getDen()); } fraction operator-(const fraction& f1, const fraction& f2) { return f1 + (-f2); } fraction operator*(const fraction& f1, const fraction& f2) { return fraction(f1.getNum() * f2.getNum(), f1.getDen() * f2.getDen()); } fraction operator/(const fraction& f1, const fraction& f2) { return fraction(f1.getNum() * f2.getDen(), f1.getDen() * f2.getNum()); } bool operator==(const fraction& f1, const fraction& f2) { return f1.getNum() == f2.getNum() && f1.getDen() == f2.getDen(); } bool operator!=(const fraction& f1, const fraction& f2) { return !(f1 == f2); } bool operator<(const fraction& f1, const fraction& f2) { return f1.getNum() * f2.getDen() < f2.getNum() * f1.getDen(); } bool operator>(const fraction& f1, const fraction& f2) { return f2 < f1; } bool operator<=(const fraction& f1, const fraction& f2) { return !(f2 < f1); } bool operator>=(const fraction& f1, const fraction& f2) { return !(f1 < f2); } istream& operator>>(istream& in, fraction& f) { char slash; in >> f.num >> slash >> f.den; f.reduce(); return in; } ostream& operator<<(ostream& out, const fraction& f) { out << f.getNum() << '/' << f.getDen(); return out; } int main() { fraction f1(1, 2), f2(3, 4), f3; cout << "f1 = " << f1 << endl; cout << "f2 = " << f2 << endl; cout << "f3 = " << f3 << endl; cout << "请输入一个分数:"; cin >> f3; cout << "f3 = " << f3 << endl; cout << "f1 + f2 = " << f1 + f2 << endl; cout << "f1 - f2 = " << f1 - f2 << endl; cout << "f1 * f2 = " << f1 * f2 << endl; cout << "f1 / f2 = " << f1 / f2 << endl; cout << "f1 == f2 ? " << (f1 == f2) << endl; cout << "f1 != f2 ? " << (f1 != f2) << endl; cout << "f1 < f2 ? " << (f1 < f2) << endl; cout << "f1 > f2 ? " << (f1 > f2) << endl; cout << "f1 <= f2 ? " << (f1 <= f2) << endl; cout << "f1 >= f2 ? " << (f1 >= f2) << endl; return 0; } ``` 上述实现中,分数类 `fraction` 的成员变量包括分子 `num` 和分母 `den`,它们在构造函数中被初始化。构造函数中还进行了分母为零的判断和分数的约分处理。`fraction` 类重载了一些运算符,包括一元负号运算符、二元加减乘除运算符和比较运算符。此外,还重载了输入输出流运算符,方便用户输入和输出分数。在主函数中,演示了如何使用这些运算符进行分数的运算和比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值