基本アルゴリズム(その1)

  1. 整数
    1. 最大公約数
    2. 素数
  2. 行列式
  3. 角度の和
  4. 平面幾何
    1. 三角形の面積
    2. 点と直線との距離
    3. 二直線の交点
    4. 点と線分との関係
    5. 二線分の交点の有無
    6. 二線分の交点
    7. 座標軸の回転
  5. 空間幾何
    1. 三点を通る平面
    2. 点と直線との距離
    3. 点と平面との距離
    4. 二直線間の最短距離
  6. 入出力
    1. 基本入出力
    2. 1文字ずつ入力
    3. 1行ずつ入力

  1. 整数

    1. 最大公約数
      #include <stdio.h>
      
      int gcd(int, int);   // 最大公約数
      
      int main()
      {
      	int n, n1, n2;
      
      	printf("2つの整数を入力してください ");
      	scanf("%d %d", &n1, &n2);
      
      	n = gcd(n1, n2);
      
      	printf("   最大公約数は %d です\n", n);
      
      	return 0;
      }
      
      /**********************/
      /* xとyの最大公約数 */
      /*      x,y : データ  */
      /**********************/
      int gcd(int x, int y)
      {
      	int r, g;
      
      	r = x % y;
      
      	if (r == 0)
      		g = y;
      	else
      		g = gcd(y, r);
      
      	return g;
      }
      			
    2. 素数
      #include <stdio.h>
      
      int prime(int);   // 素数の判定
      
      int main()
      {
      	int n, sw;
      
      	printf("整数を入力してください ");
      	scanf("%d", &n);
      
      	sw = prime(n);
      
      	if (sw > 0)
      		printf("   与えられた数は素数です\n");
      	else
      		printf("   与えられた数は素数ではありません\n");
      
      	return 0;
      }
      
      /*********************************/
      /* 素数の判定                    */
      /*      n : 整数データ           */
      /*      return : =0 : 素数でない */
      /*               =1 : 素数       */
      /*********************************/
      #include <math.h>
      
      int prime(int n)
      {
      	int i1, sw, m;
      
      	m 	= (int)sqrt((double)n);
      	sw  = (n <= 1) ? 0 : 1;
      
      	for (i1 = 2; i1 <= m && sw > 0; i1++) {
      		if (n%i1 == 0)
      			sw = 0;
      	}
      
      	return sw;
      }
      			
  2. 行列式
    #include <stdio.h>
    
    double determinant(int, double **);
    
    int main()
    {
    	double **A, d;
    	int i1, i2, n;
    
    	printf("次数は? ");
    	scanf("%d", &n);
    
    	A = new double * [n];
    	for (i1 = 0; i1 < n; i1++)
    		A[i1] = new double [n];
    
    	for (i1 = 0; i1 < n; i1++) {
    		printf("%d 行目\n", i1+1);
    		for (i2 = 0; i2 < n; i2++) {
    			printf("   %d 列目? ", i2+1);
    			scanf("%lf", &A[i1][i2]);
    		}
    	}
    
    	d = determinant(n, A);
    
    	printf("行列式の値は %f\n", d);
    
    	for (i1 = 0; i1 < n; i1++)
    		delete [] A[i1];
    	delete [] A;
    
    	return 0;
    }
    
    /****************************/
    /* 行列式の値               */
    /*      n : 行列式の次数    */
    /*      A : 行列式          */
    /*      return : 行列式の値 */
    /****************************/
    double determinant(int n, double **A)
    {
    	double d = 0.0, **B, s = 1.0;
    	int i1, i2, i3, k, m;
    
    	if (n == 1)
    		d = A[0][0];
    
    	else if (n == 2)
    		d = A[0][0] * A[1][1] - A[1][0] * A[0][1];
    
    	else {
    		m = n - 1;
    		B = new double * [m];
    		for (i1 = 0; i1 < m; i1++)
    			B[i1] = new double [m];
    		for (i1 = 0; i1 < n; i1++) {
    			for (i2 = 0; i2 < m; i2++) {
    				k = 0;
    				for (i3 = 0; i3 < n; i3++) {
    					if (i3 != i1) {
    						B[i2][k] = A[i2+1][i3];
    						k++;
    					}
    				}
    			}
    			d += s * A[0][i1] * determinant(m, B);
    			s  = -s;
    		}
    		for (i1 = 0; i1 < m; i1++)
    			delete [] B[i1];
    		delete [] B;
    	}
    
    	return d;
    }
    		
  3. 角度の和
    #include <stdio.h>
    #include <math.h>
    
    double add(double, double);
    
    int main()
    {
    	double a, a1, b, b1, c, u = atan(1.0) / 45.0;
    
    	printf("2つの角度を入力して下さい(度) ");
    	scanf("%lf %lf", &a, &b);
    
    	a1 = u * a;
    	b1 = u * b;
    
    	c  = add(a1, b1) / u;
    
    	printf("   %f + %f = %f\n", a, b, c);
    
    	return 0;
    }
    
    /****************************/
    /* 角度の和                 */
    /*      a,b : 角度          */
    /*      return : a+b(±π) */
    /****************************/
    #include <math.h>
    
    double add(double a, double b)
    {
    	double pi = 4.0 * atan(1.0), x;
    
    	x = a + b;
    	if (x > pi)
    		x -= 2.0 * pi;
    	else if (x < -pi)
    		x += 2.0 * pi;
    
    	return x;
    }
    		
  4. 平面幾何

    1. 三角形の面積
      #include <stdio.h>
      
      double triangle1(double [][2]);
      double triangle2(double [][2]);
      double add(double, double);
      
      int main()
      {
      	double a, x[3][2];
      
      	printf("点Aの座標(x1, y1)");
      	scanf("%lf %lf", &x[0][0], &x[0][1]);
      	printf("点Bの座標(x2, y2)");
      	scanf("%lf %lf", &x[1][0], &x[1][1]);
      	printf("点Cの座標(x3, y3)");
      	scanf("%lf %lf", &x[2][0], &x[2][1]);
      
      	a = triangle1(x);
      	printf("   三角形ABCの面積: %f\n", a);
      	a = triangle2(x);
      	printf("   三角形ABCの面積(ヘロンの公式): %f\n", a);
      
      	return 0;
      }
      
      /*******************************/
      /* 三角形ABCの面積             */
      /*      A : (x[0][0], x[0][1]) */
      /*      B : (x[1][0], x[1][1]) */
      /*      C : (x[2][0], x[2][1]) */
      /*      return : 面積          */
      /*******************************/
      #include <math.h>
      
      double triangle1(double x[][2])
      {
      	double area, a1, a2, ang, ba, bc, x1, y1;
      
      	x1   = x[0][0] - x[1][0];
      	y1   = x[0][1] - x[1][1];
      	a1   = atan2(y1, x1);
      	ba   = sqrt(x1 * x1 + y1 * y1);
      
      	x1   = x[2][0] - x[1][0];
      	y1   = x[2][1] - x[1][1];
      	a2   = atan2(y1, x1);
      	bc   = sqrt(x1 * x1 + y1 * y1);
      
      	ang  = fabs(add(a1, -a2));
      	area = 0.5 * ba * bc * sin(ang);
      
      	return area;
      }
      
      /****************************/
      /* 角度の和                 */
      /*      a,b : 角度          */
      /*      return : a+b(±π) */
      /****************************/
      #include <math.h>
      
      double add(double a, double b)
      {
      	double pi = 4.0 * atan(1.0), x;
      
      	x = a + b;
      	if (x > pi)
      		x -= 2.0 * pi;
      	else if (x < -pi)
      		x += 2.0 * pi;
      
      	return x;
      }
      
      /**********************************/
      /* 三角形ABCの面積(ヘロンの公式)*/
      /*      A : (x[0][0], x[0][1])    */
      /*      B : (x[1][0], x[1][1])    */
      /*      C : (x[2][0], x[2][1])    */
      /*      return : 面積             */
      /**********************************/
      #include <math.h>
      
      double triangle2(double x[][2])
      {
      	double area, a[3], s, x1, y1;
      	int i1;
      
      	for (i1 = 0; i1 < 3; i1++) {
      		x1    = x[i1][0] - x[(i1+1)%3][0];
      		y1    = x[i1][1] - x[(i1+1)%3][1];
      		a[i1] = sqrt(x1 * x1 + y1 * y1);
      	}
      
      	s    = 0.5 * (a[0] + a[1] + a[2]);
      	area = sqrt(s * (s - a[0]) * (s - a[1]) * (s - a[2]));
      
      	return area;
      }
      			
    2. 点と直線との距離
      #include <stdio.h>
      
      double p_line_2(double, double, double, double, double);   // 平面上の点と直線
      
      int main()
      {
      	double a, b, c, x0, y0, r;
      
      	printf("   直線の方程式(a, b, c)? ");
      	scanf("%lf %lf %lf", &a, &b, &c);
      	printf("   点の座標(x, y)? ");
      	scanf("%lf %lf", &x0, &y0);
      	r = p_line_2(a, b, c, x0, y0);
      	printf("      距離は %f\n", r);
      
      	return 0;
      }
      
      /************************************/
      /* 平面上の点と直線との距離         */
      /*      (x0, y0) と ax + by + c = 0 */
      /*      return : 距離               */
      /************************************/
      #include <math.h>
      
      double p_line_2(double a, double b, double c, double x0, double y0)
      {
      	double r;
      
      	r = fabs(a * x0 + b * y0 + c) / sqrt(a * a + b * b);
      
      	return r;
      }
      			
    3. 二直線の交点
      #include <stdio.h>
      
      int cross(double, double, double, double, double, double, double *);
      
      int main()
      {
      	double a1, a2, b1, b2, c1, c2, x[2];
      	int sw;
      
      	printf("直線1の方程式(a1, b1, c1)");
      	scanf("%lf %lf %lf", &a1, &b1, &c1);
      	printf("直線2の方程式(a2, b2, c2)");
      	scanf("%lf %lf %lf", &a2, &b2, &c2);
      
      	sw = cross(a1, b1, c1, a2, b2, c2, x);
      
      	if (sw == 0)
      		printf("   交点はありません!\n");
      	else
      		printf("   交点の座標:(%f, %f)\n", x[0], x[1]);
      
      	return 0;
      }
      
      /*********************************/
      /* 二直線の交点                  */
      /*      a1 * x + b1 * y + c1 = 0 */
      /*      a2 * x + b2 * y + c1 = 0 */
      /*      x : 交点の座標           */
      /*      return : =0 : 交点なし   */
      /*               =1 : 交点あり   */
      /*********************************/
      #include <math.h>
      
      int cross(double a1, double b1, double c1,
                double a2, double b2, double c2, double *x)
      {
      	double A[2][2], D, eps = 1.0e-10;
      	int sw = 0;
      
      	D = a1 * b2 - a2 * b1;
      
      	if (fabs(D) > eps) {
      		A[0][0] = b2 / D;
      		A[0][1] = -b1 / D;
      		A[1][0] = -a2 / D;
      		A[1][1] = a1 / D;
      		x[0]    = -A[0][0] * c1 - A[0][1] * c2;
      		x[1]    = -A[1][0] * c1 - A[1][1] * c2;
      		sw      = 1;
      	}
      
      	return sw;
      }
      			
    4. 点と線分との関係
      #include <stdio.h>
      
      /*************************/
      /* ベクトルの大きさの2乗 */
      /*************************/
      double norm(double *x)
      {
      	return x[0] * x[0] + x[1] * x[1];
      }
      
      /****************************/
      /* 2つのベクトルの内積      */
      /*      a,b : 2つのベクトル */
      /****************************/
      double dot(double *a, double *b)
      {
      	return a[0] * b[0] + a[1] * b[1];
      }
      
      /******************************/
      /* 2つのベクトルの外積(z成分) */
      /*      a,b : 2つのベクトル   */
      /******************************/
      double cross(double *a, double *b)
      {
      	return a[0] * b[1] - a[1] * b[0];
      }
      
      /***************************/
      /* 点と線分の関係          */
      /*      p0,p1,p2 : 3つの点 */
      /***************************/
      int ccw(double *p0, double *p1, double *p2)
      {
      	int sw = 0;
      	double a[2], b[2], EPS = 1.0e-8;
      
      	a[0] = p1[0] - p0[0];
      	a[1] = p1[1] - p0[1];
      	b[0] = p2[0] - p0[0];
      	b[1] = p2[1] - p0[1];
      	if ( cross(a, b) > EPS )   // 点p2は線分p0-p1の反時計方向
      		sw = 1;
      	else if ( cross(a, b) < -EPS )   // 点p2は線分p0-p1の時計方向
      		sw = -1;
      	else if ( dot(a, b) < -EPS )   // 点p2は線分p0-p1の手前
      		sw = 2;
      	else if ( norm(a) < norm(b) )   // 点p2は線分p0-p1の先
      		sw = -2;
      
      	return sw;   // 点p2は線分p0-p1の上
      }
      
      int main()
      {
      	double a[2], b[2], p[2];
      	int sw;
      
      	printf("線分ABにおける点Aの座標(x, y)");
      	scanf("%lf %lf", &a[0], &a[1]);
      	printf("線分ABにおける点Bの座標(x, y)");
      	scanf("%lf %lf", &b[0], &b[1]);
      	printf("点Pの座標(x, y)");
      	scanf("%lf %lf", &p[0], &p[1]);
      
      	sw = ccw(a, b, p);
      
      	if (sw == 1)
      		printf("点pは線分ABの反時計方向\n");
      	else if (sw == -1)
      		printf("点pは線分ABの時計方向\n");
      	else if (sw == 2)
      		printf("点pは線分ABの手前\n");
      	else if (sw == -2)
      		printf("点pは線分ABの先\n");
      	else
      		printf("点pは線分ABの上\n");
      
      	return 0;
      }
      			
    5. 二線分の交点の有無
      #include <stdio.h>
      
      /*************************/
      /* ベクトルの大きさの2乗 */
      /*************************/
      double norm(double *x)
      {
      	return x[0] * x[0] + x[1] * x[1];
      }
      
      /****************************/
      /* 2つのベクトルの内積      */
      /*      a,b : 2つのベクトル */
      /****************************/
      double dot(double *a, double *b)
      {
      	return a[0] * b[0] + a[1] * b[1];
      }
      
      /******************************/
      /* 2つのベクトルの外積(z成分) */
      /*      a,b : 2つのベクトル   */
      /******************************/
      double cross(double *a, double *b)
      {
      	return a[0] * b[1] - a[1] * b[0];
      }
      
      /***************************/
      /* 点と線分の関係          */
      /*      p0,p1,p2 : 3つの点 */
      /***************************/
      int ccw(double *p0, double *p1, double *p2)
      {
      	int sw = 0;
      	double a[2], b[2], EPS = 1.0e-8;
      
      	a[0] = p1[0] - p0[0];
      	a[1] = p1[1] - p0[1];
      	b[0] = p2[0] - p0[0];
      	b[1] = p2[1] - p0[1];
      	if ( cross(a, b) > EPS )   // 点p2は線分p0-p1の反時計方向
      		sw = 1;
      	else if ( cross(a, b) < -EPS )   // 点p2は線分p0-p1の時計方向
      		sw = -1;
      	else if ( dot(a, b) < -EPS )   // 点p2は線分p0-p1の手前
      		sw = 2;
      	else if ( norm(a) < norm(b) )   // 点p2は線分p0-p1の先
      		sw = -2;
      
      	return sw;   // 点p2は線分p0-p1の上
      }
      
      /************************************/
      /* 線分p1-p2と線分p3-p4の交点の有無 */
      /************************************/
      int isIntersect(double *p1, double *p2, double *p3, double *p4)
      {
      	int sw = 0;   // 交点なし
      
      	if ( ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 && ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0 )
      		sw = 1;   // 交点あり
      
      	return sw;
      }
      
      int main()
      {
      	double a[2], b[2], c[2], d[2];
      	int sw;
      
      	printf("線分ABにおける点Aの座標(x, y)");
      	scanf("%lf %lf", &a[0], &a[1]);
      	printf("線分ABにおける点Bの座標(x, y)");
      	scanf("%lf %lf", &b[0], &b[1]);
      	printf("線分CDにおける点Cの座標(x, y)");
      	scanf("%lf %lf", &c[0], &c[1]);
      	printf("線分CDにおける点Dの座標(x, y)");
      	scanf("%lf %lf", &d[0], &d[1]);
      
      	sw = isIntersect(a, b, c, d);
      
      	if (sw > 0)
      		printf("交点あり\n");
      	else
      		printf("交点なし\n");
      
      	return 0;
      }
      			
    6. 二線分の交点
      #include <stdio.h>
      #include <math.h>
      
      /*************************************/
      /* 2線分の交点                       */
      /*      A + r(B - A) と C + s(D - C) */
      /*      P : 交点の座標               */
      /*      return : =-1 : 交点が無い    */
      /*               =0 : 交点が線分の外 */
      /*               =1 : 交点がある     */
      /*************************************/
      int cross(double *A, double *B, double *C, double *D, double *P)
      {
      	double r, s, AC[2], BUNBO, EPS = 1.0e-8;
      	int sw = -1;
      
      	AC[0] = C[0] - A[0];
      	AC[1] = C[1] - A[1];
      	BUNBO = (B[0] - A[0]) * (D[1] - C[1]) - (B[1] - A[1]) * (D[0] - C[0]);
      	if (fabs(BUNBO) > EPS) {
      		r = ((D[1] - C[1]) * AC[0] - (D[0] - C[0]) * AC[1]) / BUNBO;
      		s = ((B[1] - A[1]) * AC[0] - (B[0] - A[0]) * AC[1]) / BUNBO;
      		if (r > -EPS && r < 1.0+EPS && s > -EPS && s < 1.0+EPS) {
      			P[0] = A[0] + r * (B[0] - A[0]);
      			P[1] = A[1] + r * (B[1] - A[1]);
      			sw   = 1;
      		}
      		else
      			sw = 0;
      	}
      
      	return sw;
      }
      
      int main()
      {
      	double a[2], b[2], c[2], d[2], p[2];
      	int sw;
      
      	printf("線分ABにおける点Aの座標(x, y)");
      	scanf("%lf %lf", &a[0], &a[1]);
      	printf("線分ABにおける点Bの座標(x, y)");
      	scanf("%lf %lf", &b[0], &b[1]);
      	printf("線分CDにおける点Cの座標(x, y)");
      	scanf("%lf %lf", &c[0], &c[1]);
      	printf("線分CDにおける点Dの座標(x, y)");
      	scanf("%lf %lf", &d[0], &d[1]);
      
      	sw = cross(a, b, c, d, p);
      
      	if (sw <= 0)
      		printf("No! ( %d )\n", sw);
      	else
      		printf("%f %f\n", p[0], p[1]);
      
      	return 0;
      }
      			
    7. 座標軸の回転
      /****************************/
      /* 座標軸の回転             */
      /*      coded by Y.Suganuma */
      /****************************/
      #include <stdio.h>
      #include <math.h>
      
      int main()
      {
      	double a, x = 1.0, y = 1.0, X, Y;
      					// 座標軸を45度回転する
      	a = 45.0 * M_PI / 180.0;
      	X = x * cos(a) + y * sin(a);
      	Y = -x * sin(a) + y * cos(a);
      
      	printf("x %f y %f\n", x, y);
      	printf("X %f Y %f\n", X, Y);
      
      	return 0;
      }
      			
  5. 空間幾何

    1. 三点を通る平面
      #include <stdio.h>
      #include <math.h>
      
      void plane(double [][3], double []);
      double determinant(int, double **);
      
      int main()
      {
      	double ABCD[4], x[3][3], eps = 1.0e-10;
      
      	printf("1番目の点の座標(x1, y1, z1) ");
      	scanf("%lf %lf %lf", &x[0][0], &x[0][1], &x[0][2]);
      	printf("2番目の点の座標(x2, y2, z2) ");
      	scanf("%lf %lf %lf", &x[1][0], &x[1][1], &x[1][2]);
      	printf("3番目の点の座標(x3, y3, z3) ");
      	scanf("%lf %lf %lf", &x[2][0], &x[2][1], &x[2][2]);
      
      	plane(x, ABCD);
      
      	if (fabs(ABCD[0]) > eps) {
      		if (ABCD[0] > 0)
      			printf("   %f x", ABCD[0]);
      		else
      			printf("   -%f x", -ABCD[0]);
      	}
      	if (fabs(ABCD[1]) > eps) {
      		if (ABCD[1] > 0)
      			printf(" + %f y", ABCD[1]);
      		else
      			printf(" - %f y", -ABCD[1]);
      	}
      	if (fabs(ABCD[2]) > eps) {
      		if (ABCD[2] > 0)
      			printf(" + %f z", ABCD[2]);
      		else
      			printf(" - %f z", -ABCD[2]);
      	}
      	if (fabs(ABCD[3]) > eps) {
      		if (ABCD[3] > 0)
      			printf(" + %f", ABCD[3]);
      		else
      			printf(" - %f", -ABCD[3]);
      	}
      	printf(" = 0\n");
      
      	return 0;
      }
      
      /*****************************/
      /* 三点を通る平面            */
      /*      Ax + Bx + Cx + D = 0 */
      /*      x : 3点             */
      /*      ABCD : A, B, C, D    */
      /*****************************/
      void plane(double x[][3], double ABCD[])
      {
      	double **A;
      	int i1;
      
      	A = new double * [3];
      	for (i1 = 0; i1 < 3; i1++)
      		A[i1] = new double [3];
      
      	A[0][0] = x[0][1];
      	A[0][1] = x[0][2];
      	A[0][2] = 1.0;
      	A[1][0] = x[1][1];
      	A[1][1] = x[1][2];
      	A[1][2] = 1.0;
      	A[2][0] = x[2][1];
      	A[2][1] = x[2][2];
      	A[2][2] = 1.0;
      	ABCD[0] = determinant(3, A);
      
      	A[0][0] = x[0][0];
      	A[0][1] = x[0][2];
      	A[0][2] = 1.0;
      	A[1][0] = x[1][0];
      	A[1][1] = x[1][2];
      	A[1][2] = 1.0;
      	A[2][0] = x[2][0];
      	A[2][1] = x[2][2];
      	A[2][2] = 1.0;
      	ABCD[1] = -determinant(3, A);
      
      	A[0][0] = x[0][0];
      	A[0][1] = x[0][1];
      	A[0][2] = 1.0;
      	A[1][0] = x[1][0];
      	A[1][1] = x[1][1];
      	A[1][2] = 1.0;
      	A[2][0] = x[2][0];
      	A[2][1] = x[2][1];
      	A[2][2] = 1.0;
      	ABCD[2] = determinant(3, A);
      
      	A[0][0] = x[0][0];
      	A[0][1] = x[0][1];
      	A[0][2] = x[0][2];
      	A[1][0] = x[1][0];
      	A[1][1] = x[1][1];
      	A[1][2] = x[1][2];
      	A[2][0] = x[2][0];
      	A[2][1] = x[2][1];
      	A[2][2] = x[2][2];
      	ABCD[3] = -determinant(3, A);
      
      	for (i1 = 0; i1 < 3; i1++)
      		delete [] A[i1];
      	delete [] A;
      }
      
      /****************************/
      /* 行列式の値               */
      /*      n : 行列式の次数    */
      /*      A : 行列式          */
      /*      return : 行列式の値 */
      /****************************/
      double determinant(int n, double **A)
      {
      	double d = 0.0, **B, s = 1.0;
      	int i1, i2, i3, k, m;
      
      	if (n == 1)
      		d = A[0][0];
      
      	else if (n == 2)
      		d = A[0][0] * A[1][1] - A[1][0] * A[0][1];
      
      	else {
      		m = n - 1;
      		B = new double * [m];
      		for (i1 = 0; i1 < m; i1++)
      			B[i1] = new double [m];
      		for (i1 = 0; i1 < n; i1++) {
      			for (i2 = 0; i2 < m; i2++) {
      				k = 0;
      				for (i3 = 0; i3 < n; i3++) {
      					if (i3 != i1) {
      						B[i2][k] = A[i2+1][i3];
      						k++;
      					}
      				}
      			}
      			d += s * A[0][i1] * determinant(m, B);
      			s  = -s;
      		}
      		for (i1 = 0; i1 < m; i1++)
      			delete [] B[i1];
      		delete [] B;
      	}
      
      	return d;
      }
      			
    2. 点と直線との距離
      #include <stdio.h>
      
      double p_line_3(double, double, double, double, double,
                      double, double, double, double);   // 空間内の点と直線
      
      int main()
      {
      	double x0, x1, y0, y1, z0, z1, ram, myu, nyu, r;
      
      	printf("   直線の方程式(x0, y0, z0)? ");
      	scanf("%lf %lf %lf", &x0, &y0, &z0);
      	printf("               (λ, μ, ν)? ");
      	scanf("%lf %lf %lf", &ram, &myu, &nyu);
      	printf("   点の座標(x1, y1, z1)? ");
      	scanf("%lf %lf %lf", &x1, &y1, &z1);
      	r = p_line_3(x0, y0, z0, ram, myu, nyu, x1, y1, z1);
      	printf("      距離は %f\n", r);
      
      	return 0;
      }
      
      /**********************************************************************/
      /* 空間内の点と直線の距離                                             */
      /*      (x1, y1, z1) と (x - x0) / λ = (y - y0) / μ = (z - z0) / ν */
      /*         λ,μ,ν:方向余弦                                       */
      /*      return : 距離                                                 */
      /**********************************************************************/
      #include <math.h>
      
      double p_line_3(double x0, double y0, double z0, double ram, double myu, double nyu,
                      double x1, double y1, double z1)
      {
      	double x, y, z, w, r;
      
      	x = x1 - x0;
      	y = y1 - y0;
      	z = z1 - z0;
      	w = ram * x + myu * y + nyu * z;
      	r = sqrt(fabs(x * x + y * y + z * z - w * w));
      
      	return r;
      }
      			
    3. 点と平面との距離
      #include <stdio.h>
      
      double p_plane(double [], double []);
      
      int main()
      {
      	double ABCD[4], x[3], h;
      
      	printf("点の座標(x1, y1, z1) ");
      	scanf("%lf %lf %lf", &x[0], &x[1], &x[2]);
      	printf("平面の方程式(A, B, C, D) ");
      	scanf("%lf %lf %lf %lf", &ABCD[0], &ABCD[1], &ABCD[2], &ABCD[3]);
      
      	h = p_plane(x, ABCD);
      
      	printf("   距離: %f\n", h);
      
      	return 0;
      }
      
      /*****************************/
      /* 点と平面の距離            */
      /*      Ax + Bx + Cx + D = 0 */
      /*      x : 点               */
      /*      ABCD : A, B, C, D    */
      /*****************************/
      #include <math.h>
      
      double p_plane(double x[], double ABCD[])
      {
      	double h;
      
      	h = fabs(ABCD[0] * x[0] + ABCD[1] * x[1] + ABCD[2] * x[2] + ABCD[3]) /
              sqrt(ABCD[0] * ABCD[0] + ABCD[1] * ABCD[1] + ABCD[2] * ABCD[2]);
      
      	return h;
      }
      			
    4. 二直線間の最短距離
      #include <stdio.h>
      
      double line_line(double, double, double, double, double, double,
                       double, double, double, double, double, double);
      double determinant(int, double **);
      double p_line_3(double, double, double, double, double, double,
                      double, double, double);
      
      int main()
      {
      	double x1, x2, y1, y2, z1, z2, u1, u2, v1, v2, w1, w2, r;
      
      	printf("直線1の方程式\n");
      	printf("   点(x1, y1, z1)? ");
      	scanf("%lf %lf %lf", &x1, &y1, &z1);
      	printf("   方向比(u1, v1, w1)? ");
      	scanf("%lf %lf %lf", &u1, &v1, &w1);
      
      	printf("直線2の方程式\n");
      	printf("   点(x2, y2, z2)? ");
      	scanf("%lf %lf %lf", &x2, &y2, &z2);
      	printf("   方向比(u2, v2, w2)? ");
      	scanf("%lf %lf %lf", &u2, &v2, &w2);
      
      	r = line_line(x1, y1, z1, u1, v1, w1, x2, y2, z2, u2, v2, w2);
      
      	printf("      距離は %f\n", r);
      
      	return 0;
      }
      
      /******************************************************/
      /* 二直線間の最短距離                                 */
      /*      (x - x1) / u1 = (y - y1) / v1 = (z - z1) / w1 */
      /*         u1,v1,w1:方向比                         */
      /*      (x - x2) / u2 = (y - y2) / v2 = (z - z2) / w2 */
      /*         u2,v2,w2:方向比                         */
      /*      return : 距離                                 */
      /******************************************************/
      #include <math.h>
      
      double line_line(double x1, double y1, double z1, double u1, double v1, double w1,
                       double x2, double y2, double z2, double u2, double v2, double w2)
      {
      	double **A, D, x, y, z, r = 0.0, eps = 1.0e-10, ram, myu, nyu;
      	int i1;
      
      	x = v1 * w2 - v2 * w1;
      	y = w1 * u2 - w2 * u1;
      	z = u1 * v2 - u2 * v1;
      	D = sqrt(x * x + y * y + z * z);
      					// 2直線が平行でない場合
      	if (D > eps) {
      		A = new double * [3];
      		for (i1 = 0; i1 < 3; i1++)
      			A[i1] = new double [3];
      
      		A[0][0] = x2 - x1;
      		A[0][1] = y2 - y1;
      		A[0][2] = z2 - z1;
      		A[1][0] = u1;
      		A[1][1] = v1;
      		A[1][2] = w1;
      		A[2][0] = u2;
      		A[2][1] = v2;
      		A[2][2] = w2;
      
      		r = fabs(determinant(3,A)) / D;
      
      		for (i1 = 0; i1 < 3; i1++)
      			delete [] A[i1];
      		delete [] A;
      	}
      					// 2直線が平行な場合
      	else {
      		x   = sqrt(u1 * u1 + v1 * v1 + w1 * w1);
      		ram = u1 / x;
      		myu = v1 / x;
      		nyu = w1 / x;
      		r   = p_line_3(x1, y1, z1, ram, myu, nyu, x2, y2, z2);
      	}
      
      	return r;
      }
      
      /****************************/
      /* 行列式の値               */
      /*      n : 行列式の次数    */
      /*      A : 行列式          */
      /*      return : 行列式の値 */
      /****************************/
      double determinant(int n, double **A)
      {
      	double d = 0.0, **B, s = 1.0;
      	int i1, i2, i3, k, m;
      
      	if (n == 1)
      		d = A[0][0];
      
      	else if (n == 2)
      		d = A[0][0] * A[1][1] - A[1][0] * A[0][1];
      
      	else {
      		m = n - 1;
      		B = new double * [m];
      		for (i1 = 0; i1 < m; i1++)
      			B[i1] = new double [m];
      		for (i1 = 0; i1 < n; i1++) {
      			for (i2 = 0; i2 < m; i2++) {
      				k = 0;
      				for (i3 = 0; i3 < n; i3++) {
      					if (i3 != i1) {
      						B[i2][k] = A[i2+1][i3];
      						k++;
      					}
      				}
      			}
      			d += s * A[0][i1] * determinant(m, B);
      			s  = -s;
      		}
      		for (i1 = 0; i1 < m; i1++)
      			delete [] B[i1];
      		delete [] B;
      	}
      
      	return d;
      }
      
      /**********************************************************************/
      /* 空間内の点と直線との距離                                           */
      /*      (x1, y1, z1) と (x - x0) / λ = (y - y0) / μ = (z - z0) / ν */
      /*         λ,μ,ν:方向余弦                                       */
      /*      return : 距離                                                 */
      /**********************************************************************/
      #include <math.h>
      
      double p_line_3(double x0, double y0, double z0, double ram, double myu, double nyu,
                      double x1, double y1, double z1)
      {
      	double x, y, z, w, r;
      
      	x = x1 - x0;
      	y = y1 - y0;
      	z = z1 - z0;
      	w = ram * x + myu * y + nyu * z;
      	r = sqrt(fabs(x * x + y * y + z * z - w * w));
      
      	return r;
      }
      			
  6. 入出力

    1. 基本入出力
      /***************************************************/
      /* 基本入出力                                      */
      /*      スペースや改行で区切られたデータの読み込み */
      /*      (スペースや改行を読み込むことは出来ない) */
      /*      coded by Y.Suganuma                        */
      /***************************************************/
      #include <stdio.h>
      
      int main()
      {
      	double d_data;
      	int i_data;
      	char c, str[5];
      
      	FILE *in = fopen("data", "r");
      	while (fscanf(in, "%lf %d %c %s", &d_data, &i_data, &c, str) != EOF)
      		printf("%.2f %5d %c %s\n", d_data, i_data, c, str);
      
      	fclose(in);
      
      	return 0;
      }
      
      /*  入力データ例
      3.141592654 123 a ab
      1.2
      12345
      A
      ABC
      */
      			
    2. 1文字ずつ入力
      /*********************************************/
      /* 1文字ずつ入力                            */
      /*      int fgetc(FILE *stream)              */
      /*           stream : FILE構造体へのポインタ */
      /*      coded by Y.Suganuma                  */
      /*********************************************/
      #include <stdio.h>
      
      int main()
      {
      	int i1 = 0;
      	char str[100];
      
      	FILE *in = fopen("data", "r");
      	while ((str[i1] = fgetc(in)) != EOF)
      		i1++;
      	str[i1] = '\0';
      	printf("%s", str);
      
      	fclose(in);
      
      	return 0;
      }
      
      /*  入力データ例
      3.141592654 123 a ab
      1.2
      12345
      A
      ABC
      */
      			
    3. 1行ずつ入力
      /*******************************************************/
      /* 1行ずつ入力                                        */
      /*      char *fgets(char *string, int n, FILE *stream) */
      /*           string : 読み込んだデータの格納場所       */
      /*           n      : 読み込む文字数                   */
      /*           stream : FILE構造体へのポインタ           */
      /*      文字の読込は,改行文字('\n')が現れるか,ファ */
      /*      イルの終端に達するか,または,読み込んだ文字数 */
      /*      が(指定された文字数-1)になるまで行われます */
      /*      改行文字は読み込み格納されます.文字列の最後に */
      /*      はNULL文字('\0')が付加されます.fgets関数のス*/
      /*      トリームを標準入力ストリーム(stdin)とすれば,*/
      /*      gets関数とほとんど同じですが,gets関数では,改 */
      /*      行文字をNULL文字に置き換えます.成功すると読み */
      /*      込んだ文字列に対するポインタを返します.       */
      /*      coded by Y.Suganuma                            */
      /*******************************************************/
      #include <stdio.h>
      
      int main()
      {
      	char str[25];
      
      	FILE *in = fopen("data", "r");
      	while (fgets(str, 25, in) != NULL)
      		printf("%s", str);
      
      	fclose(in);
      
      	return 0;
      }
      
      /*  入力データ例
      3.141592654 123 a ab
      1.2
      12345
      A
      ABC
      */