以下の問題を解こう.

あるクラスの男子学生は女子学生よりも2人多く,クラスには全部で40人の学生がいる.このクラスの男子学生の人数,女子学生の人数をそれぞれ求めよ.

簡単な連立方程式を解けば解答できるが,連立方程式を用いなくても,男子学生の人数は$(2 + 40)/2 = 21$,女子学生の人数は$(40 - 2)/2 = 19$と,それぞれ与えられた数の「和」と「差」を用いて解答することができる. こうした問題は和差算と呼ばれている.小学校で習った人も居るだろう. ここでは和差算を解くプログラムを作成しよう.


問題


標準入力から2個の整数$a, b (a < b)$を読み込み,標準出力に$(a + b)/2$および$(b - a)/2$の計算結果を書き出すプログラムを作成せよ.

ただし,入力される2つの整数$a, b$は半角スペースで区切られているものとする. プログラムは以下の仕様を満たすこと.

  1. $a + b$と$b - a$の一方もしくは両方が奇数だった場合は,ERRORと標準出力に出力せよ.
  2. $-100 < a < b < +100$を満たさない場合は,ERRORと標準出力に出力せよ.
  3. 計算結果は$(a + b)/2, (b - a)/2$の順にスペース区切りで標準出力に出力せよ.
  4. 各表示の末尾には改行文字\nを付けること.\は,バックスペースと呼び,キーボードので入力する.

実行例


#は標準入力,>は標準出力を表す.

# 4 8
> 6 2
# -10 2
> -4 6
# 10 19
> ERROR

ヒント



「課題の進め方」



手順例


問題は以下の通りである.

「標準入力から2個の整数$a, b (a < b)$を読み込み,標準出力に$(a + b)/2$および$(b - a)/2$の計算結果を書き出すプログラムを作成せよ.」

まずは単純に問題だけを考えてプログラムをかいてみる.プログラミングをうまくするコツは問題を分解して部分ごとに構築していくのがよい.

  1. (標準入力から) 2個の整数$a, b (a < b)$を読み込み
  2. $(a + b)/2$, $(b - a)/2$を計算
  3. (標準出力に) 計算結果を書き出す

この分解した手順通りに書いてみる


0. 準備

#include <stdio.h>

int main()
{
  return 0;
}

1. 2個の整数$a, b (a < b)$を読み込み

#include <stdio.h>

int main()
{
  int xxx, yyy;
  scanf("%d %d", &xxx, &yyy);
  return 0;
}

2. 計算

#include <stdio.h>

int main()
{
  int xxx, yyy, zzz, vvv;
  scanf("%d %d", &xxx, &yyy);
  zzz = (xxx + yyy)/2;
  vvv = (yyy - xxx)/2;
  return 0;
}

3. 計算結果を書き出す

#include <stdio.h>

int main()
{
  int xxx, yyy, zzz, vvv;
  scanf("%d %d", &xxx, &yyy);
  zzz = (xxx + yyy)/2;
  vvv = (yyy - xxx)/2;
  printf("%d %d", zzz, vvv);
  return 0;
}

条件


4. 条件「$a + b$と$b - a$の一方もしくは両方が奇数だった場合は,ERRORと標準出力に出力]

#include <stdio.h>

int main()
{
  int xxx, yyy, zzz, vvv;
  scanf("%d %d", &xxx, &yyy);
  zzz = (xxx + yyy);
  vvv = (yyy - xxx);

  zzz = zzz/2;
  vvv = vvv/2;
  printf("%d %d", zzz, vvv);
  return 0;
}
#include <stdio.h>

int main()
{
  int xxx, yyy, zzz, vvv;
  scanf("%d %d", &xxx, &yyy);
  zzz = (xxx + yyy);
  vvv = (yyy - xxx);
  if (zzz ###### || vvv ######) {
    printf("ERROR");
  } 
  else {
    zzz = zzz/2;
    vvv = vvv/2;
    printf("%d %d", zzz, vvv);
  }
  return 0;
}

5. 条件「各表示の末尾には改行文字\nを付けること」


最後に



参考情報



変数の宣言と代入,型



条件分岐(if文,else節)と比較演算子



標準入力からデータを読み込むための関数,たとえばscanf関数,fgets関数



標準出力に出力するための関数,たとえばprintf関数,puts関数



剰余算の演算子%



余談


和差算の応用として,以下のような数当てゲームが有名である.

  1. 相手に異なる2つの数字(0から9まで)を思い浮かべてもらう
  2. 思い浮かべてもらった数字を並べて2桁の数を作るとき,(大きい数) - (小さい数) を計算し,9で割る
  3. 思い浮かべてもらった数字を並べて2桁の数を作るとき,(大きい数) + (小さい数) を計算し,11で割る
  4. 相手に手順2と3の答えを教えてもらい,それぞれ$a, b$としてプログラムに入力すると,相手が思い浮かべた数字を推定できる

例えば,相手が2と7を思い浮かべたときは,$(72-27)/9 = 5, (72+27)/11 = 9$であるから,$(a, b) = (5, 9)$を教えてもらうことになる. これらの値をプログラムに入力すると7 2が出力され,相手が思い浮かべた数字になっていることが確認できる.