2011
12/9
第15回 演習のヒント
演習のヒント
課題0(練習)
解答例は提示済み.解答例をそのまま提出すれば6点.実行結果を変えないように自分で書き換えられたら最大12点.
//課題0解答例
#include <stdio.h>
int main(void)
{
int input,output;
scanf("%d",&input); //scanfを使うことで,キーボードからinputへ入力
output = input * 16; //inputを使った計算式を計算して,結果をoutputへ代入
printf("%x\n",output); //printfを使うことで,outputの内容を画面に出力
return 0;
}
課題1
10/25の練習シートの4.に解答例が書いてある.
//10/25の練習シートの4.(穴埋め問題)
#include <stdio.h>
int main(void)
{
//変数の宣言をするところ
____________________________________________ //課題1では半径,距離,角度
_____________________ //半径=5; 半径は固定値
scanf(__________________________________ ); // xの値を入力.“ 必要な書式 ”, 変数名, ...
//プログラムの本体(計算式など)を書くところ
___________________________________________ //角度=計算式
printf(_________________________________ ); // “必要な書式”, 出力したい計算結果
return 0;
}
課題2
大枠のプログラムは次のようになる.
#include <stdio.h>
int main(void)
{
int cmd;
scanf("%d",&cmd); //scanfで命令cmdを入力
if(エラーになる条件)
printf("エラーの表示");
else if(
//
// この部分でifとelseを組み合わせて,問題の要求に適合するように出力をprintfする.
//
//すべての条件に合わなかった時
printf("No\n");
return 0;
}
ここで,解き方としては次の二つが考えられる.
方針1. 課題2のページにあるように,出力は8通りしかない.そこでその8通りになるような条件式を7つ考える.(最後の一つはelseで済む)
if(出力1になるような条件)
printf("出力1");
else if(出力2になるような条件)
printf("出力2");
else if ....
...
else if(出力7になるような条件)
printf("出力7");
else
printf("出力8");
ただし,条件式は緻密に考える必要がある.例えば,"Up"とだけ表示する条件は,2の倍数であることだけではなく,3の倍数ではないこと,5の倍数ではないこと,マイナスの数ではないことも条件となる.この場合の条件式は次のようになる.
(cmd%2==0 && cmd%3!=0 && cmd%5!=0 && cmd>=0)
方針2. すべての場合分けのフローをちゃんと考える.課題2にあるようにマイナスの数かどうか,2の倍数かどうか,3の倍数かどうか,5の倍数かどうか,順番に全部質問してその結果の枝分かれを考える.どのように枝を選択しても少なくとも先ほどの4つの質問が全部されるように気をつけてフローを考える.
マイナスの数か? YES -> Errorと表示 ->終了
NO -> 2の倍数か YES -> Upと表示 -> 3の倍数か? YES/NOと以下に続く...
NO -> 3の倍数か? YES/NOと以下に続く...
上記のフローを完成させ,下に書いたプログラム例のように質問?のところをひとつのif文に置き換えれば,プログラムが完成する.
if(マイナスの数か?)
{
//YESのところ
printf("Error\n");
//ここで終了
}
else
{
//NOのところ
if(2の倍数か?)
{
printf("Up");
if(3の倍数か?)
{
}
else
{
}
}
else
{
if(3の倍数か?)
{
}
else
{
}
}
}
課題3
#include <stdio.h>
int main(void)
{
double t,v,y,ylimit; //時間,速度,落下距離,目的落下距離
scanf("%lf",&ylimit); //scanfを使うことで,キーボードから目的落下距離ylimitへ入力
for(t=0.0; 終了条件 ; t+=0.1) //時間は0.1秒おきに計算,0->0.1->0.2->0.3->...
{
v = t秒後の落下速度の計算式;
y = t秒後の落下距離の計算式;
}
printf("%lf\n",v); //ylimitを越えた瞬間の落下速度を表示
return 0;
}
課題4
#include <stdio.h>
int gcd(int m, int x); //m>xとしてmとxの最大公約数を求めて返す関数
int main(void)
{
int m,n,g;
m=9699690;
scanf("%d", &n);
g = gcd( m, n);
printf("%d\n",g);
}
int gcd(int m,int x)
{
/* ユークリッドの互助法を使って最大公約数を求める
Step 1. もしx=0であればreturn m;として終了
Step 2. mをxで割った余りをrとする
Step 3. m=x, x=rとして、Step 1.へ
*/
}
課題5
#include <stdio.h>
int find(char str[]); //文字配列strの中から文字パターン"abc"を探してその位置(先頭からの文字数)を返す
int main(void)
{
int x;
char str[999]; //最大999文字まで
scanf("%s", str);
x = find( str);
printf("%d\n",x);
return 0;
}
int find(char str[])
{
int no;
s=1;
for(no=0; str[no]!=\0 ; no++)
switch(s)
{
case 1:
if(str[no]が'a'だったら)
s = 状態1から遷移する先の状態番号;
else
s = 1; //状態1のまま
break;
case 2:
状態2から遷移する条件と,遷移先を同様にプログラム
break;
case ... 以下必要な状態
case ゴールの状態
成功したときの処理
break;
}
}
課題6
#include <stdio.h>
int fill(int x, int y);
int input[9][9] = {
{0,1,1,0,0,0,0,0,0},
{1,1,0,1,1,1,1,1,0},
{0,0,0,0,1,0,1,0,0},
{1,1,0,0,1,1,1,0,0},
{1,0,0,0,1,1,0,0,0},
{0,0,0,0,0,1,0,0,0},
{0,1,1,1,1,1,1,0,1},
{0,1,0,0,0,0,0,1,0},
{1,0,0,0,0,0,0,1,0}
};
int output[9][9] = {
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
};
int main(void)
{
int x,n;
scanf("%d", &x); //xをキーボードから入力
n = fill(x, x); //座標x,xから塗りつぶすことにする
printf("%d\n",n);
return 0;
}
int fill(int x, int y)
{
int left,right,up,down;
座標(x,y)がinputの範囲外であればダメ(0を返す)
inputの座標(x,y)を調べる.黒(1)でなければダメ(0を返す)
outputの座標(x,y)を調べる.すでに出力があれば(1ならば)ダメ(0を返す)
そうでないなら
outputの(x,y)を黒(1)に置き換える.
自分の上下左右を調べる.
つまり,left = fill(x-1, y);
right = fill(x+1,y);
up = fill(x,y-1);
down = fill(x,y+1);
返値は,left+right+up+down+1; //+1は自分自身の1画素分
}
