【问题描述】
Vistar喜欢数学。一天,他遇到一道数学题,题目给出了许多二元一次方程,这些方程均为Ax+By+C=0的形式。题目要求Vistar将这些方程的全部交点求出。
Vistar的数学不好,所以他希望你帮他解决这个问题。
【输入形式】
第 1 行包含一个正整数 N,表示方程组中方程的个数。
接下来 N 行,每行包含A、B、C三个整数,表示一个形如“Ax+By+C=0”形式的二元一次方程。
对于100%的测试数据,N、A、B、C≤100。输入数据保证每个方程均构成一条直线,且任意两条直线之间有且仅有一个交点。
【输出形式】
输出共 N - 1 行,第 i 行包含 N - i 组数字,每组两个数。第 i 行的第 j 组数字表示第 i 个方程与第 i + j 个方程交点的横纵坐标,相邻两个数之间用一个空格分隔。
输出时,仅输出整数部分。例如,你应当将“1.55”输出为“1”,“2.001”输出为“2”。特别地,若整数部分为“-0”,你应当将其输出为“0”。
【样例输入】
3 1 1 4 5 1 4 1 2 3
【样例输出】
0 -4 -5 1 0 -1
【样例说明】
联立方程 x+y+4=0 和 5x+y+4=0,解得 x=0,y=-4。
联立方程 x+y+4=0 和 x+2y+3=0,解得 x=-5,y=1。
联立方程 5x+y+4=0 和 x+2y+3=0,解得 x=-5/9,y=-11/9,整数部分分别为0和-1。
【提示】
使用浮点数可能导致精度误差,存在避免误差的解法。
思路:最开始是打算直接把两个式子的系数分别统一来计算x和y
eg:2x+3y+1=0和3x+6y+2=0,就是说直接变成6x+9y+3=0和6x+12y+4=0来求y,变成12x+18y+6=0和9x+18y+6=0来求x,这样也可以避免浮点数。
但是实际中可能会出现某些系数为0的方程式,可能会造成运行时错误,需要把所有方程式类型讨论到才能避免,过于麻烦,所以最后还是屈服于线性代数的克拉默法则。
完整代码:
#include <iostream>
using namespace std;
struct equ
{
int A;
int B;
int C;
};
void cal(equ x,equ y)
{
int rx=0,ry=0;
rx=(-x.C*y.B+x.B*y.C)/(x.A*y.B-x.B*y.A);
ry=(-x.A*y.C+x.C*y.A)/(x.A*y.B-x.B*y.A);
cout << rx << " " << ry << " ";
}
int main()
{
int N=0;
cin >> N;
equ* all=new equ[N];
for (int i=0; i<N; i++) cin >> all[i].A >> all[i].B >> all[i].C;
for (int i=0; i<N-1; i++)
{
for (int j=i+1; j<N; j++) cal(all[i],all[j]);
cout << endl;
}
return 0;
}