fork download
  1. #include<stdio.h>
  2.  
  3. int gcdf(int x, int y){
  4. return(y == 0 ? x :gcdf(y , x%y) ); /*最大公約数を求める*/
  5. }
  6.  
  7. int gcd(int a, int b){
  8. /* ★負だった場合に自信がないので敢えて追加 */
  9. int c = (a >= 0) ? a : -a ;
  10. int d = (b >= 0) ? b : -b ;
  11.  
  12. return(c > d ? gcdf(c, d) : gcdf(d, c)); /*恐らくここも間違いの1つ、gcd(a,a)をどうなおせばいいか*/
  13. /* ★まぁ考えなくていいといえば良い。 商が0で余りが出るとき結局逆転するからね */
  14. }
  15.  
  16. int main(void){
  17. int buf[2]; /*データ保存*/
  18. int i, j, k; /*カウンタ*/
  19. int g; /* ★この公約数はカウンタではない。ベストアンサーもらってから編集 */
  20. int n = 4; /*配列の次数*/
  21.  
  22.  
  23. int a[4][4][2] = {
  24. {{1,1},{2,1},{0,1},{1,2}}, /*問題の行列*/
  25. {{0,1},{2,3},{1,1},{0,1}},
  26. {{1,1},{0,1},{0,1},{-1,1}},
  27. {{1,1},{0,1},{-1,2},{-1,1}}
  28. };
  29.  
  30. int inv_a[4][4][2] = {
  31. {{1,1},{0,1},{0,1},{0,1}}, /*単位行列*/
  32. {{0,1},{1,1},{0,1},{0,1}},
  33. {{0,1},{0,1},{1,1},{0,1}},
  34. {{0,1},{0,1},{0,1},{1,1}}
  35. };
  36. for(i = 0; i < n; i++){
  37.  
  38. buf[0] = a[i][i][1]; //分子
  39. buf[1] = a[i][i][0]; //分母
  40.  
  41.  
  42. for(j = 0; j < n; j++){
  43.  
  44. a[i][j][0] *= buf[0];
  45. a[i][j][1] *= buf[1];
  46.  
  47. g = gcd(a[i][j][0], a[i][j][1]);
  48.  
  49. a[i][j][0] = a[i][j][0] / g;
  50. a[i][j][1] = a[i][j][1] / g; //約分
  51.  
  52.  
  53. inv_a[i][j][0] *= buf[0];
  54. inv_a[i][j][1] *= buf[1];
  55.  
  56. g = gcd(inv_a[i][j][0], inv_a[i][j][1]);
  57.  
  58. inv_a[i][j][0] = inv_a[i][j][0] / g;
  59. inv_a[i][j][1] = inv_a[i][j][1] / g; //約分
  60.  
  61. }
  62. /* ★ ピボット選択の必要性については面倒なので検討してません */
  63. for(j = 0; j < n; j++){
  64.  
  65. if(i != j){ /* ★分岐は1行でいいの? =>多分駄目…自信ないけど。Guard Clauseみたいに早めに次ループを回しても良いかも */
  66.  
  67. buf[0] = a[j][i][0];
  68. buf[1] = a[j][i][1];
  69.  
  70. for(k = 0; k < n; k++){
  71.  
  72. a[j][k][0] = a[j][k][0] * a[i][k][1] * buf[1] - a[j][k][1] * a[i][k][0] * buf[0];
  73. a[j][k][1] = a[j][k][1] * a[i][k][1] * buf[1];
  74.  
  75. g = gcd(a[j][k][0], a[j][k][1]);
  76.  
  77. a[j][k][0] = a[j][k][0] / g;
  78. a[j][k][1] = a[j][k][1] / g;
  79.  
  80.  
  81. inv_a[j][k][0] = inv_a[j][k][0] * inv_a[i][k][1] * buf[1] - inv_a[j][k][1]* inv_a[i][k][0] * buf[0];
  82.  
  83. inv_a[j][k][1] = inv_a[j][k][1] * inv_a[i][k][1] * buf[1];
  84.  
  85. g = gcd(inv_a[j][k][0], inv_a[j][k][1]);
  86.  
  87. inv_a[j][k][0] = inv_a[j][k][0] / g;
  88. inv_a[j][k][1] = inv_a[j][k][1] / g;
  89.  
  90. }
  91. }
  92. }
  93. }
  94.  
  95.  
  96. /* ★改行入れたりして見やすさ改善 */
  97. printf("1 2 0 1/2 \n 0 2/3 1 0 \n 1 0 0 -1 \n 1 0 -1/2 -1 \nの逆行列は以下の通り\n");
  98.  
  99. for(i = 0; i < n; i++){ /*逆行列出力*/
  100. for(j = 0; j < n; j++){
  101. if(inv_a[i][j][1] < 0){ /* ★条件にミスがある。そもそも代入するな */
  102. inv_a[i][j][0] *= (-1);
  103. inv_a[i][j][1] *= (-1); /*分母のマイナスをプラスに*/
  104. }
  105.  
  106. /*分母が1の時に整数表示*/
  107.  
  108. if(inv_a[i][j][1] != 1){
  109. printf("%d/%d ", inv_a[i][j][0],inv_a[i][j][1]);
  110. }
  111. else{
  112. printf("%d ", inv_a[i][j][0]);
  113. }
  114. }
  115. printf("\n");
  116. }
  117.  
  118. return 0;
  119. }
Success #stdin #stdout 0s 9432KB
stdin
Standard input is empty
stdout
1 2 0 1/2 
 0 2/3 1 0 
 1 0 0 -1 
 1 0 -1/2 -1 
の逆行列は以下の通り
2/3 -2 13/3 -4 
0 3/2 -3 3 
0 0 2 -2 
2/3 -2 10/3 -4