题解 P2026 求一次函数解析式

小邱

2021-02-08 17:37:46

Personal

一次函数解析式,函数就是类似于f()这种函数,最高次是一次 [题目传送门](https://www.luogu.com.cn/problem/P2026) 题意就是求$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 之后的我们代码上见吧! ```cpp #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记录](https://www.luogu.com.cn/record/46247318)