一次函数解析式,函数就是类似于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记录