题解 P2026 【求一次函数解析式】

· · 题解

数学题目,可以用来加深理解二元一次方程组的通解。

希望更好的食用体验?点击在Ta的博客里查看

大家应该都知道的,二元一次方程组通常会有代入法和加减法等求解方式。看其他的博客里都没有详细讲到如何解一般的二元一次方程组。下面,我们先来推导出一般二元一次方程组的通解。

设我们有以下的方程组:

\begin{cases}ax+by=m&...(1)\\cx+dy=n&...(2)\end{cases}

我们下面用的是加减消元法,读者也可以用代入消元法尝试求出二元一次方程组的通解,有想法的咱们私信。

我们先想着消x,于是乎,将(1)式乘c可得:

acx+bcy=cm

再将(2)式乘a可得:

acx+ady=an

然后就可以得到这样的方程组:

\begin{cases}acx+bcy=cm&...(3)\\acx+ady=an&...(4)\end{cases}

然后(3)式减(4)式,就可以很愉快地消掉x啦,这时就只剩:

(bc-ad)y=cm-an \therefore y=\frac{cm-an}{bc-ad}

同理,我们再用类似的方法消掉y(具体请读者自行尝试,提示:将(1) (2)式中y的系数变为一个量)。得到:

(ad-bc)x=dm-bn \therefore x = \frac{dm-bn}{ad-bc} $$\begin{cases}x=\frac{dm-bn}{ad-bc}\\y=\frac{cm-an}{bc-ad}\end{cases}$$ 然后,这个题目跟上面的式子有什么关系呢? 学过一次函数的都知道,一次函数的解析式一般为$y=kx+b$,所以这样的函数在图像中会经过点$(x,y)$。 所以,我们不妨设其经过的两个点的坐标为$(m,n),(p,q)$,将这两个点的坐标代入$y=kx+b$就有: $$\begin{cases}mk+b=n\\pk+b=q\end{cases}$$ 这下你就明白了,根据上面$\begin{cases}ax+by=m\\cx+dy=n\end{cases}$的解为$\begin{cases}x=\frac{dm-bn}{ad-bc}\\y=\frac{cm-an}{bc-ad}\end{cases}$我们可代入求得: $$\begin{cases}k=\frac{n-q}{m-p}\\b=\frac{pn-mq}{p-m}\end{cases}$$ 所以,这道题目的轮廓就出来了,然后我们再考虑细节问题: 1. $\frac{n-q}{m-p}$是不是整数?不是的话该怎么约分?$\frac{pn-mq}{p-m}$呢? 2. 如何处理系数是负数的情况? 3. 什么时候该省略项? 我们一一解决这些问题: A1: $\frac{n-q}{m-p}$是不是整数,只需要看$n-q$是否能被$m-p$整除,即是否有$(n-q)~mod~(m-p)=0$就可以了,如果不是的话,约分也好办,取$\gcd(n-q,m-p)$,然后这两个数分别除以这个最大公因数。 注意!$n-q$和$m-p$尽量用一个变量来存储!$\gcd(n-q,m-p)$也用一个变量来存储。 A2: 如果是分子是负数,并且分母也是负数,就全部都转为正就行了,单有分子是负数更加不用变,分母是负数也全部取相反数。 A3:当x或常数项的系数为0的时候,不用输出。 具体来看看代码加深理解吧: ```cpp #include <cstdio> #include <algorithm> using namespace std; int m, n, p, q, a, b; //y=ax+b int gcd(int a, int b) { return a % b == 0 ? b : gcd(b, a % b); } int main() { scanf("%d%d%d%d", &m, &n, &p, &q); printf("y="); int t1 = n - q, t2 = m - p, t3 = p * n - m * q, t4 = p - m; if(t1 % t2) { if(gcd(t1, t2) != 1) { int g = gcd(t1, t2); t1 /= g; t2 /= g; } if(t2 < 0) t2 = -t2, t1 = -t1; printf("%d/%d*x", t1, t2); } else if(t1 / t2) printf("%dx", t1 / t2); if(t3 % t4) { // printf("%d %d %d %d\n", t3, t4, t3<0, t4<0); if(gcd(t3, t4) != 1) { int g = gcd(t3, t4); // printf("%d %d %d %d\n", t3, t4, t3<0, t4<0); t3 /= g; t4 /= g; } // printf("%d %d %d %d\n", t3, t4, t3<0, t4<0); if(t4 < 0) t3 = -t3, t4 = -t4; // printf("%d %d %d %d\n", t3, t4, t3<0, t4<0); if(t3 < 0) printf("%d/%d", t3, t4); else printf("+%d/%d", t3, t4); } else if(t3 / t4 < 0) printf("%d", t3 / t4); else if(t3 / t4) printf("+%d", t3 / t4); return 0; } ``` 写本文时间仓促,若有纰漏,请用博客置顶声明中的联系方式与我取得联系。 当然,我写得这么用心,不给个赞和五星好评再走嘛?