Ex09Ans

From Prog0

Jump to: navigation, search

演習第9回

Contents

解答例

A問題

A-1 行列の主対角線にある要素値

ファイル名: ex09a1.c

#include <stdio.h>

int main()
{
  int i, j, mat[][3]={{1, 2, 3},
                      {4, 5, 6},
                      {7, 8, 9}};
  
  for (i=0;i<3; i++){
    for (j=0;j<3; j++){
      printf("%d ", mat[i][j]);
    }
    printf("\n");  
  }

  printf("行列の主対角線にある要素値\n");
  for (i=0;i<3; i++){
    printf("%d ", mat[i][i]);
  }
  printf("\n");  
 
  return 0; 
}

A-2 行列とマクロ

ファイル名: ex09a2.c

#include <stdio.h>
#define ROW 2
#define COL 3

int main()
{
  int i, j;
  int mat1[ROW][COL],mat2[ROW][COL],mat3[ROW][COL]; 
  
  printf("%d x %d 行列[mat1]の要素を入力してください:\n", ROW, COL);
  for(i = 0; i < ROW; i++)
    for(j = 0; j < COL; j++)
      scanf("%d", &mat1[i][j]);
      
  printf("%d x %d 行列[mat2]の要素を入力してください:\n", ROW, COL);
  for(i = 0; i < ROW; i++)
    for(j = 0; j < COL; j++)
      scanf("%d", &mat2[i][j]);
      
  for(i = 0; i < ROW; i++) { 
    for(j = 0; j < COL; j++) { 
      mat3[i][j] = mat1[i][j] + mat2[i][j]; 
    } 
  }
  
  printf("[mat1]と[mat2]の和は:\n");
  for(i = 0; i < ROW; i++){
    for(j = 0; j < COL; j++){
      printf("%d ", mat3[i][j]);
    }
    printf("\n");
  }
 
  return 0;
}

A-3 配列形状の変換

#include <stdio.h>

int main()
{
  int i, j, m, n;
  int inarray[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  int mat1[5][3], mat2[3][5];
  
  /* 1次元配列から5x3配列への変換 */
  for (i=0; i<5; i++){
    for (j=0; j<3; j++){ 
      mat1[i][j]=inarray[i*3+j];
    } 
  }

  printf("1次元配列から5x3配列への変換結果\n");
  for (i=0; i<5; i++){
    for (j=0; j<3; j++){
      printf("%2d ", mat1[i][j]); 
    }
    printf("\n");
  }


  /* 5x3配列から3x5配列への変換 */
  for (i=0; i<5; i++){
    for (j=0; j<3; j++){ 
      m = (3*i+j)/5;
      n = (3*i+j)%5;
      mat2[m][n] = mat1[i][j];
    } 
  }

  printf("5x3配列から3x5配列への変換結果\n");
  for (i=0; i<3; i++){
    for (j=0; j<5; j++){
      printf("%2d ", mat2[i][j]); 
    }
    printf("\n");
   }
 return 0;
}

B問題

B-1 行列要素の抜き出し

ファイル名: ex09b1.c

#include <stdio.h>
#define ROW 4
#define COL 3

int main()
{
  int i, j, mode, sel;
  int mat[ROW][COL]={{1, 3, 5},{2, 4, 6},{7, 9, 11},{8, 10, 12}};
 
  printf("行要素と列要素のどちらを表示したいか選択して下さい\n");
  printf("(行要素:0, 列要素:1)  ");
  scanf("%d", &mode);

  if (mode==0) {
    printf("表示したい行番号を入力して下さい :");
    scanf("%d",&sel);
    if (sel >= 0 && sel<ROW){
      for (j=0; j<COL; j++){
        printf("%2d ", mat[sel][j]);
      }
    }else{
      printf("行の範囲外です");
    }
      printf("\n");
  } else if (mode==1) {
    printf("表示したい列番号を入力して下さい :");
    scanf("%d",&sel);
    if (sel >=0 && sel<COL){
      for (i=0; i<ROW; i++){
          printf("%2d\n", mat[i][sel]);
      }
    }else{
      printf("列の範囲外です\n");
    }
  } else {
    for (i=0; i<ROW; i++) {
      for (j=0; j<COL; j++) {
        printf("%2d ",mat[i][j]);
      }
      printf("\n");
    }
  }
  return 0;
}

B-2 2次元配列の一部の利用と行列のスカラー倍

ファイル名: ex09b2.c

#include <stdio.h>
#define SIZE 10

int main()
{
  int i, j, n, m, s;
  int mat[SIZE][SIZE];
 
  /* 配列要素への入力 */
  printf("行列の大きさを入力して下さい(最大10 x 10) :");
  scanf("%d%d",&n,&m);
  printf("%d x %d行列を整数値で入力してください\n", n, m);
  for (i=0; i<n; i++){
    for (j=0; j<m; j++){ 
      scanf("%d", &mat[i][j]); 
    } 
  }


  /* スカラー値の入力 */
  printf("行列を何倍にしますか? ");
  scanf("%d", &s);
 
  /* スカラー倍の処理:処理をこの二重ループで行わずに表示時に行ってもよい */
  for (i=0; i<n; i++){
    for (j=0; j<m; j++){ 
      mat[i][j] = mat[i][j]*s; 
    } 
  }
 
  /* 結果の表示 */
  for (i=0; i<n; i++){
    for (j=0; j<m; j++){
      printf("%2d ", mat[i][j]); /* スカラー倍の処理を表示時に行ってもよい */
    }
    printf("\n");
  }
 
 return 0;
}

Extra問題

E-1 〇×三目並べゲーム

ファイル名: ex09e1.c

#include <stdio.h>
#define NUM 3

int main()
{
  int map[NUM][NUM];
  int i, j, m, n;
  int flag = 0;
  int endflag;
  int sum;
  int win = 0;

  /* 配列の初期化 */
  for (i=0; i<NUM; i++)
    for (j=0; j<NUM; j++)
      map[i][j] = 0;

  while (1) {
    /* 盤の表示 */
    for (i=0; i<NUM; i++) {
      for (j=0; j<NUM; j++) {
        if (map[i][j]==1) printf("(%d %d) 〇 ", i, j);
        else if (map[i][j]==-1) printf("(%d %d) × ", i, j);
        else printf("(%d %d)   ", i, j);
      }
      printf("\n");
    }

    /* 終了判定(勝敗が決まった時) */
    /*  行チェック */
    for (i=0; i<NUM; i++) {
      sum = 0;
      for (j=0; j<NUM; j++) {
        sum += map[i][j];
      }
      if (sum==NUM) win = 1;
      if (sum==-NUM) win = -1;
    }
	
    /*  列チェック */
    for (j=0; j<NUM; j++) {
      sum = 0;
      for (i=0; i<NUM; i++) {
        sum += map[i][j];
      }
      if (sum==NUM) win = 1;
      if (sum==-NUM) win = -1;
    }

    /*  右下がり斜めチェック */
    sum = 0;
    for (i=0; i<NUM; i++) {
      sum += map[i][i];
    }
    if (sum==NUM) win = 1;
    if (sum==-NUM) win = -1;

    /*  左下がり斜めチェック */
    sum = 0;
    for (i=0; i<NUM; i++) {
      sum += map[i][NUM-i-1];
    }
    if (sum==NUM) win = 1;
    if (sum==-NUM) win = -1;
    if (win==1) {printf("〇の勝ち!!\n"); break;}
    else if (win==-1) {printf("×の勝ち!!\n"); break;}

    /* 終了判定(盤面が埋まった時) */
    endflag = 0;
    for (i=0; i<NUM; i++)
      for (j=0; j<NUM; j++)
        if (map[i][j]==0) endflag = 1;
    if (endflag==0) {
      printf("引き分け\n");
      break;
    }

    /* 座標の入力 */
    if (flag==0) {
      printf("〇の番です\n座標を行・列の順で入力してください:");
      scanf("%d%d", &m, &n);
      if (m<0 || m>=NUM || n<0 || n>=NUM) {
        printf("盤の範囲外です\n");
        continue;
      }
      if (map[m][n]!=0) {
        printf("そこには打てません!\n");
        continue;
      }
      map[m][n] = 1;
      flag = 1;
    } else {
      printf("×の番です\n座標を行・列の順で入力してください:");
      scanf("%d%d", &m, &n);
      if (m<0 || m>=NUM || n<0 || n>=NUM) {
    	 printf("盤の範囲外です\n");
        continue;}
      if (map[m][n]!=0) {
    	 printf("そこには打てません!\n");
        continue;
      }
      map[m][n] = -1;
      flag = 0;
     }
  }

  return 0;
}
Personal tools