P2026 求一次函数解析式

题目描述 给定两个整点的坐标,求它们所在直线的函数解析式(一次函数)。

输入格式 输入共两行。第一行有两个整数x1,y1。表示第一个整点的坐标为(x1,y1)第二行有两个整数x2,y2。表示第二个整点的坐标为(x2,y2)

输出格式 输出共一行,即这个函数解析式。

输入输出样例

输入 #1
3 6
2 4

输出 #1
y=2x

输入 #2
3 5
2 7
输出 #2
y=-2x+11
输入 #3
3 -1
5 -2
输出 #3
y=-1/2*x+1/2
哇连复制键本身都能粘贴的吗这么神奇吗

首先,求一次函数解析式的数学步骤应该人人皆知,即对于经过点(x1,y1),(x2,y2)的一次函数y=kx+b,有
            k=(y2-y1)/(x2-x1),
            b=y1-kx1.
我觉得这个题太好做了,然而看到第三组数据的时候,我惊呆了。
要分数的啊!!!这就表明double是绝对不行的了!
看了看题解(发誓没有抄袭,借鉴都没有),里面的大佬们都用了各种花里胡哨的解法,好几个if语句写了将近两行,明显是在判断是不是需要分数。
然而,作为学过面向对象程序设计的我,觉得用结构体是个不错的选择!(面向对象中的“类”和结构体非常相像,然而noi只教结构体,我曾大为不满)
我们可以用一个结构体"fs"表示分数,在里面实现各种分数的各种功能。包括两个变量分子和分母以及输出函数。但是需要注意的是,上述求k和b的算式中有分数与整数的乘法(kx1)以及分数和分数的减法(y1-kx1)因此需要编写结构体fs的operator*(int)和operator-(fs)函数。
输出函数output,在里面完成各种判断,例如当分子为0是不输出,分母为1时只输出分子,其他情况输出"分子/分母”的形式。
同时,这里也有一个需要注意的地方。我们要在输出分数时输出其符号。但是对于k,若分数值为正,不用输出正号,但b就要输出了(负号就都一样了,都要输出)。于是需要告诉output函数一个参数,表示需不需要输出正符号。
当然,最重要的是求最大公约数的函数,使分数能够对于输入的分子和分母进行约分,以及分数相减时的通分。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
    return (a%b==0)?b:gcd(b,a%b);//辗转相除法 
}
struct point
{
    int x;
    int y;
}p1,p2;
struct fs
{
    int fenzi;
    int fenmu;
    bool zheng;//正数或0为true,负数为false 
    void yue(int &a,int &b)//模拟约分,因为要修改分子和分母本身的值,因此用引用。 
    {
        int p=gcd(a,b);
        a/=p;
        b/=p;
    }
    fs(int a,int b)//a/b,初始化的构造函数 
    {
        if(a*b>0) zheng=true;//判断正负 
        else zheng=false;
        if(gcd(a,b)==1)//不用约分 
        {
            fenzi=a;
            fenmu=b;
        }
        else//其实不用再特判一下,直接除就行 
        {
            int p=gcd(a,b);
            a/=p;
            b/=p;
            fenzi=a;
            fenmu=b;
        }
    }
    fs operator*(int a)
    {
        fs r(this->fenzi*a,fenmu);
        return r;
    }
    fs operator-(fs a)
    {
        fs r(fenzi*a.fenmu-fenmu*a.fenzi,fenmu*a.fenmu);//a/b-c/d==(ad-bc)/bd
        return r;
    }
    void output(bool NEED_TO_OUTPUT_ZHENG)//NEED_TO_OUTPUT_ZHENG表示是否需要在分数值为正时输出正号 
    {
        if(fenzi==0) return;//分子是0,不用输出 
        yue(fenzi,fenmu);//再约分一下保险 
        if(zheng==true&&NEED_TO_OUTPUT_ZHENG==true)//正数且要输出正号 
        {
            cout<<"+";
        }
        else if(zheng==false)//负数 
        {
            cout<<"-";
        }
        if(fenmu==1)
        {
            if(fenzi==1||fenzi==-1) return;//题目中,只要是分数,后面就跟乘号,因此这样能过 
            else cout<<abs(fenzi);//符号已经输出了 
        }
        else
        {
            cout<<abs(fenzi)<<"/"<<abs(fenmu);//最普通的情况 
        }
    }
};
int main()
{
    cin>>p1.x>>p1.y>>p2.x>>p2.y;
    fs k(p1.y-p2.y,p1.x-p2.x);
    fs temp_y(p1.y,1);//临时的一个分数形式的y1,能够让其成功调用operator-函数 
    fs b=temp_y-(k*p1.x);
    cout<<"y=";
    k.output(0);//不输出正号 
    if(k.fenmu!=1)
    {
        cout<<"*";
    }
    cout<<"x";
    b.output(1);//输出正号 
    return 0;
}



原文地址:https://www.cnblogs.com/jiangyuechen/p/12380325.html