H18年秋季基本情報技術者試験の午後の問3*1(n元1次方程式・ガウスの消去法)を解いてみました。
/* * H18秋午後 問3 */ #include <stdio.h> void gauss(int n, double *a[], double *b, double *x); void answer_print(int n, double *x); int main() { int i, j, n; double **a; double *b; double *x; printf("n元1次方程式 => n = "); scanf("%d", &n); a = (double **)malloc(sizeof(double *) * n); b = (double *)malloc(sizeof(double) * n); x = (double *)malloc(sizeof(double) * n); if (a == NULL || b == NULL || x == NULL) { printf("error: malloc\n"); exit(1); } for (i = 0; i < n; i++) { a[i] = (double *)malloc(sizeof(double) * n); if (a[i] == NULL) { printf("error: malloc\n"); exit(1); } } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("a[%d][%d] = ", i + 1, j + 1); scanf("%lf", &a[i][j]); } printf("b[%d] = ", i + 1); scanf("%lf", &b[i]); } gauss(n, a, b, x); answer_print(n, x); for (i = 0; i < n; i++) { free(a[i]); } free(a); free(b); free(x); return 0; } void gauss(int n, double *a[], double *b, double *x) { int k, i, j; double pivot, factor, sum; /* 前進消去 */ for (k = 0; k < n - 1; k++) { pivot = a[k][k]; for (i = k + 1; i < n; i++) { factor = a[i][k] / pivot; for (j = k + 1; j < n; j++) { a[i][j] = a[i][j] - a[k][j] * factor; } b[i] = b[i] - b[k] * factor; } } /* 後退代入 */ x[n - 1] = b[n - 1] / a[n - 1][n - 1]; for (i = n - 1; i >= 0; i--) { sum = 0.0; for (j = i + 1; j < n; j++) { sum += a[i][j] * x[j]; } x[i] = (b[i] - sum) / a[i][i]; } } void answer_print(int n, double *x) { int i; printf("\n------ Answer ------\n"); for (i = 0; i < n; i++) { printf("x[%d] = %.2f\n", i + 1, x[i]); } }
を実行すると以下のようになります。
% ./gauss n元1次方程式 => n = 3 a[1][1] = 2.0 a[1][2] = 1.0 a[1][3] = 2.0 b[1] = 2.0 a[2][1] = 3.0 a[2][2] = 2.0 a[2][3] = 1.0 b[2] = 6.0 a[3][1] = 2.0 a[3][2] = 4.0 a[3][3] = 1.0 b[3] = 9.0 ------ Answer ------ x[1] = 1.00 x[2] = 2.00 x[3] = -1.00