传送门
题目描述
已知n元线性一次方程组。
其中:n<=50, 系数是整数<=100(有负数),bi的值都是整数且<300(有负数)(特别感谢U14968 mmqqdd提出题目描述的说明)(redbag:是mqd自己要我写的= =).
编程任务:
根据输入的数据,编程输出方程组的解的情况。
输入格式
第一行:未知数的个数。以下n行n+1列:分别表示每一格方程的系数及方程右边的值。
输出格式
如果方程组无实数解输出-1;
如果有无穷多实数解,输出0;
如果有唯一解,则输出解(小数点后保留两位小数)。
输入
3
2 -1 1 1
4 1 -1 5
1 1 1 0
输出
x1=1.00
x2=0
x3=-1.00
首先这道题已经把方程列出来了,算是单纯的板子题了。具体的就不多说了,知识有一些需要注意的已经放在了代码的注释里面。
AC代码如下:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
typedef int ii;
#define int long long
using namespace std;
const int MOD = 7;
const int MAXN = 110;
double a[MAXN][MAXN];//增广矩阵
double x[MAXN];//解集
bool free_x[MAXN];//标记是否是不确定的变元
int p;
inline int gcd(int a,int b) {
return b?gcd(b,a%b):a;
}
inline int lcm(int a,int b) {
return a/gcd(a,b)*b;
}
int Gauss(int equ,int var) { //qeu代表方程数,val代表变元个数
ii i,j,k;
int max_r,ta,tb,free_x_num, free_index, LCM;
int col;//当前处理的列
double temp;
for(int i = 0; i <= var; i++) {
x[i] = 0;
free_x[i] = true;
}
col = 0;
for(k = 0; k<equ && col<var; k++,col++) {
max_r = k;
for(i = k+1; i < equ; i++) {
if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
}
if(max_r!=k) { //与第k行交换
for(j = k; j < var+1; j++) swap(a[k][j],a[max_r][j]);
}
if(a[k][col]==0) { //最大的还是为0,即下面的全为0,直接跳到下一行
k--;
continue;
}
for(i = k+1; i < equ; i++) { //经证实,这里会爆long long的,所以不能用整数的找最小公倍数了,所以只能开浮点型矩阵
if(a[i][col]!=0) {
double t=a[i][col]/a[k][col];
// LCM = lcm(abs(a[i][col]),abs(a[k][col]));
// ta = LCM/fabs(a[i][col]);
// tb = LCM/fabs(a[k][col]);
// if(a[i][col]*a[k][col] < 0) tb = -tb;//异号的情况是相加
for(j = col; j < var+1; j++) {
// a[i][j] = (a[i][j]*ta-a[k][j]*tb);
a[i][j]-=t*a[k][j]; //避免爆long long,注释掉的做法是整形的,但是会爆long long
}
}
}
}
for(i = k; i < equ; i++) { //无解
if(a[i][col]!=0) return -1;
}
if(k < var) {
return (var-k);//自由变元个数
}
for(i = var-1; i>=0; i--) { //计算唯一解
temp = a[i][var];
for(j = i+1; j<var; j++) {
if(a[i][j]!=0) temp -= a[i][j]*x[j];
}
x[i] = 1.0*temp/a[i][i];
}
return 0;
}
signed main() {
int i,j;
int T;
cin>>T;
for(ii i=0;i<T;i++){
for(ii j=0;j<T+1;j++){
cin>>a[i][j];
}
}
int ans=Gauss(T,T);
if(ans==-1)puts("-1"); //无解
else if(ans>0)puts("0"); //这里的ans返回的是变元的个数,属于无穷解的情况,但是题目里面说了要输出0
else
for(ii i=0;i<T;i++)
if(x[i]==0) printf("x%d=0\n",i+1); //为了防止出现-0的情况
else printf("x%d=%.2lf\n",i+1,x[i]);
return 0;
}