题解 P2026 求一次函数解析式

一次函数解析式,函数就是类似于f()这种函数,最高次是一次

题目传送门

题意就是求$x$到$y$的公式,这个公式可以表示为:$ax+b=y$,$a,b$都是要求的数

而这是我们就可以转换成一个二元一次方程组:$$ \begin{cases} x1a+b=y1\\ x2a+b=y2 \end{cases} $$

用上式减去下试得出:$x1a-x2a=y1-y2$,提取公因数$a$得$a(x1-x2)=y1-y2$,则$$a=\frac{y1-y2}{x1-x2}$$

那么a知道了,b就好求了:$y1-x1a=b$

我们将a带入:$b=y1-\frac{x1(y1-y2)}{x1-x2}$

这时我们也想让$y1$有分母$(x1-x2)$,怎么办呢?

为了让$b$不变,所以我们让$y1$变成$y1*(x1-x2)/(x1-x2)$

之后提取分母:$b=(y1(x1-x2)-x1(y1-y2))/(x1-x2)$

乘法分配律一下:$b=\frac{y1x1-y1x2-x1y1-x1y2}{x1-x2}$

发现$x1y1=y1x1$,抵消掉

则最终的b为:$(y1x2-x1y2)/(x1-x2)$

但是,你以为就这么简单吗???

不可能!

首先看a的情况:

整数:0,-1,1,其它

分数:需化简,>0,<0

b的情况:

整数:0,>0,<0

分数:需化简,<0,>0

之后的我们代码上见吧!

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int x1,a1,a2,x2,g,y1,y2;
    bool x=0;
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);//输入
    a1=y1-y2;//a1为a的分子
    a2=x1-x2;//a2为a的分母
    printf("y=");//由于不管什么情况都有y=,所以提前输出
    if(a1%a2==0)//整数
    {
        if(a1/a2==0)//0
        {
            x=1;//做一个标记,告诉b是整数是不要输出加号
        }
        if(a1/a2==1)//1
        {
            printf("x");//由于系数为1,所以只需要输出x即可
        }
        else if(a1/a2==-1)//-1和1一样,但只需要多输出一个负号即可
        {
            printf("-x");
        }
        else//其它情况
        {
            printf("%dx",a1/a2);//直接求出整数结果
        }
    }
    else//分数
    {
        g=__gcd(abs(a1),abs(a2));//__gcd是系统函数,可以直接调用,用g保存一下分子分母公因数,这样可以少计算
        //注意了,分数*x输出是要加*号
        if(a1*a2<0)//负数
        {
            printf("-%d/%d*x",abs(a1/g),abs(a2/g));//abs一下,因为分子分母不可以出现负号,所以已经在前面加上了,且如果a*b<0,那么a/b一定也<0(初中数学知识)
        }
        else//正数,因为0在整数里面
        {
            printf("%d/%d*x",a1/g,a2/g);//这里没有用abs是因为a1和a2除以g以后一定会是正数
        }
    }
    a1=x1*y2-x2*y1;//求b的分子
    a2=x1-x2;//b的分母
    if(a1*a2<0)//如果小于零,先输出-号,以后就可以不考虑了
    {
        printf("-");
    }
    else if(a1*a2>0)
    {
        if(!x)//如果a不为0,输出加号,原因和<0一样
            printf("+");
    }
    else//=0
    {
        if((y1-y2)*1.0/(x1-x2)==0)//如果a也是0,b也是0,就输出0
            cout<<0;
        return 0;//不参与后面的运算
    }
    if(a1%a2==0)//整数,直接输出
    {
        printf("%d",a1/a2);//符号已经在之前输出了
    }
    else//分数
    {
        g=__gcd(a1,a2);//求分子分母的最大公约数
        printf("%d/%d",abs(a1/g),abs(a2/g));//输出,符号也已经输出了,不需要考虑a1/g和a2/g是否是负数,因为前面已经判断了
    }
    return 0;
}

这是我发题解的习惯: AC记录


发表于 2021-02-08 17:37:46 in 未分类