PHP 問題:紙の張り合わせ
-新しく学んだこと-
・print_r( )
・for繰り返し
問題:
折り紙を連結して 1 枚の大きな紙の垂れ幕を作ることにしました。
各折り紙は 1 辺の長さが D cm 、すなわち縦 D cm × 横 D cm の正方形です。これらの折り紙を、左右に長く伸びた直線を基準に貼り付けていきます。ただし、各折り紙について、いずれか 1 辺がちょうど直線に重なるようにします。
また、 1 枚目を貼り付けたあと、 2 枚目以降は以下のルールに従って順に貼り付けていきます。
・1 つ前に貼り付けた折り紙の右辺からみて、 1 cm 以上 D/2 cm 以下だけ重なるように貼り付ける。(下図に例を示しています。)
上記のルールを守って作られたある垂れ幕について、基準の直線を平面座標の x 軸とみなして、2 枚目以降の各折り紙における 1 つ前の折り紙への重なり具合が与えられます。
1 枚になった垂れ幕部分の面積を計算してください。
例えば、入力例 1 では以下のように計算できます。
入力例1
3 4 枚数 1辺の長さ
2 重なる長さ1
1 重なる長さ2
出力 36
プログラミングの前にフローチャートを作ります。
プログラムに直すと
3行目:垂れ幕の面積用の箱$mensekiを用意します。
4行目:重なっていない長さ用の箱$kasaneを用意します。
5行目:垂れ幕横の長さ用の箱$yokoを用意します。
6行目:入力が終わるまで{ }内の処理を繰り返します。
7行目:入力を配列$stdin_arrayに入れます。
$stdin_array[0]=3 4
$stdin_array[1]=2
$stdin_array[2]=1
となります。
9行目:配列$kamiを用意します。今回は、$stdin_array[0]=3 4を3と4に分けるために用意しました。
10行目:中身が無くなるまで繰り返し、$valueの箱に$stdin_arrayの数字を入れます。
11行目:$valueの中身に空白があれば区切り、$kamiの箱へ入れます。
$kami[0]=3
$kami[1]=4
$kami[2]=2
$kami[3]=1
となります。
13行目:$yokoの箱に$kami[1]の数字を入れます。
14行目:$countの箱に2を入れ、$countの数字が$kami[1]の数字以下である間は{ }の処理を繰り返します。繰り返す毎に$countの数字に1加算します。
15行目:重なっていない長さ=1辺の長さ-重なる長さ
16行目:垂れ幕横の長さ=垂れ幕横の長さ+重なっていない長さ
18行目:垂れ幕の面積=一辺の長さ×横の長さ
19行目:垂れ幕の面積を出力する。
・print_r(表示したい式や値)
情報をわかりやすく表示したい時に使います。
筆者は、11行目で配列の内容が上手くいっているかを確認するために
12行目にprint_r($kami);を追記しました。確認後は消しています。
・for(初期化式;条件式;変化式){ }
初期化式は、for分の処理が開始される時に1度だけ実行されます。条件に使う変数などを初期化する式が入ります。
条件式は、繰り返すかどうかの判断する式が入ります。
変化式は、繰り返しが1回行われる毎に、変数などを変化させたい時に使います。
PHP 問題:渋滞情報
-新しく学んだこと-
・複数行の標準入力
・foreachで繰り返し
・文字列の結合
問題:
ある道路の車の数と、各車の車間距離が与えられるので、車間距離が M メートル以下の場合を渋滞と定義したとき、渋滞の区間が合計で何メートルあるか求めてください。
入力は以下のルールがあります。
X Y
M-2
・・・
M-[N-1]
1行目には、車の数Xと渋滞になる距離が半角スペースで区切られます。
2行目からは、先頭から数えてM番目とM+1番目の車間間隔を表します。
入力例1
5 10
5
6
25
4
答え
15
プログラミングの前に動きのイメージをします。
プログラムに直すと
4行目:カウントを用意します。今回は、車間距離が入力の2行目から始まるので2を入れています。
5行目:車間距離の合計用の箱を用意します。
6行目:入力が終わるまで{}内の命令を繰り返します。
7行目:入力を$num_arrayに入れます。
$num_array[0] = 5 10
$num_array[1] = 5
$num_array[2] = 6
$num_array[3] = 25
$num_array[4] = 4
となります。
9行目:$each_valueという箱を用意します。今回は、$num_array[0] = 5 10を、5と10に分けるために用意しました。
10行目:中身が無くなるまで繰り返し、$valueの箱に$num_arrayの数字を移します。
11行目:$valueの中身に空白があれば区切り、$each_valueの箱へ入れます。
$each_value[0] = 5
$each_value[1] = 10
$each_value[2] = 5
$each_value[3] = 6
$each_value[4] = 25
$each_value[5] = 4
となります。
13行目:カウント(~番目の車)が車の数より小さい間は、{}内の命令を繰り返します。
14行目:車両間隔が渋滞距離以下かを判断します。
15行目:車両間隔が渋滞距離以下ならば、合計に車両間隔を加算していきます。
17行目:カウントに+1していきます。次の$each_value[]を参照するため。
・複数行の標準入力
まず、入力された数字を1行ごとに分けてから、空白が有るなら区切り、1種類の箱に結合していきます。
今回は、1行目の数字が空白で区切られていること、複数行の入力があることから、
6行目~12行目の命令をしています。
・foreach(要素を取り出す配列,取り出した要素を格納する変数)
配列の要素の数だけ命令を繰り返します。
今回は、$num_arrayの数字を$each_valueの箱に入れています。
・array_merge(最初の配列名,追加する配列1,追加する配列2,,,)
最初の配列の後に、追加する配列を連ねていきます。
PHP 問題:プレゼント企画
-新しく学んだこと-
・標準入力の空白区切り
・条件式 AかつB
・繰り返し
問題:
あなたは、プレゼント企画を実施しました。
プレゼントはAとBの2種類があります。
当選者は以下の条件に従って、選ばれます。
・Xの倍数番目はプレゼントA
・Yの倍数番目はプレゼントB
応募者毎に当選情報を出力してください。プレゼントAとBの両方当選した人はAB,Aだけ当選した人はA,Bだけ当選した人はB,どちらも当選してない人はNを表示してください。
入力例1
5 2 4
答え
N
A
N
AB
N
プログラミングの前に動きのイメージをします。
プログラムに直すと
3行目:必要の無い行です。プレゼントの種類を入れるつもりでした。
4行目:応募者の~番目を入れるための箱を用意しました。
5行目:入力された数字を$numに入れます。
6行目:$numを対象に空白で区切り、$array[0~2]それぞれに数字を入れます。
$array[0]は、応募者。$array[1]は、Xの倍数。$array[2]は、Yの倍数です。
7行目:応募者の番目が応募者数より小さい間は、8~19行目の命令を続けます。
8行目:番目の数字に+1します。(最初は1番目となります)
9行目:Xで割り切れる かつ Yで割り切れる番目なのかを判断します。
10行目:9行目の条件に合えば”AB”を表示します。
12行目:9行目の条件に合わず、Xで割り切れる番目なのかを判断します。
13行目:12行目の条件に合えば”A”を表示します。
15行目:9行目の条件に合わず、Yで割り切れる番目なのかを判断します。
16行目:15行目の条件に合えば”B”を表示します。
18行目:9、12、15行目の条件に合わなければ、”N”を表示します。
・explode(区切り文字,対象)
対象の文字列を区切り文字で分割します。
今回は、5 2 4の文字列を対象に空白(” ”)を区切り文字としています。
・条件式 &&
条件式を組み合わせたい場合につかいます。
今回は、A && B AかつBである場合を使っています。
他には
A || B AもしくはB当てはまる。
A xor B AかBのどちらか1つだけが当てはまる。
などがあります。
・while(条件式){}
条件式に合うあいだは、{}内の命令を繰り返します。
今回は、応募者の番目が応募者数より小さいあいだは を条件式にしています。
PHP 問題:文字の装飾
-新しく学んだこと-
・文字数のカウント
・文字列の埋め方
・複数行の表示
問題:入力された文字列の周囲を”+”で枠のように囲んで表示させてください。
入力例1 Paiza
答え +++++++
+Paiza+
+++++++
プログラミングの前に動きのイメージをします。
プログラムに直すと
3行目:全体用の箱を用意します。
4行目:”+”の行が入る箱を用意します。
5行目:文字数のカウント用の箱を用意します。
6行目:入力された文字を$mojiに受け取ります。
7行目:文字数を$kazuに入れます。
8行目:文字数+2を上限に”+”を$kazariに入れます。
9行目:文字数+2を上限として、$mojiの両脇へ”+”を加えて、$mojikazariに入れます。
10行目:<<< EOMからEOM; までの命令を$zenに入れます。
14行目:$zenを出力します。
・mb_strlen(対象)
対象内の文字を数えます。英数字・ひらがな区別無く1文字は1つとして数えます。
・str_pad(埋めたい文字列,合計で何文字にするか,埋める文字,どこを埋めるか)
入力例1では、Paizaを埋めたい文字列、文字列+2を上限として、”+”を埋める文字、両埋めとしています。
右埋め:STR_PAD_RIGHT
左埋め:STR_PAD_LEFT
両埋め:STR_PAD_BOTH
・= <<< EOM ~ EOM;
ヒアドキュメントといわれます。
<<<がヒアドキュメントの合図で、この次に書いた文字が再び現れるまですべて=に設定された箱(変数)へ入れます。ここに入力された通りに表示したい時、複数行を表示したい時に役立ちます。
PHP 問題:奇数か偶数か
-新しく学んだこと-
・条件文if
問題:
入力される整数が奇数であれば「odd」と出力し、偶数であれば「even」と出力されるようにしてください。
入力例1 4 答え even
入力例2 5 答え odd
入力例3 2 答え even
出力最終行の末尾に改行を入れ、余計な文字、空白を含んではいけません。
プログラミングの前に動きのイメージします。
プログラムに直すと
3行目:入力された整数を$kazuの箱に入れます。
4行目:条件文ifを用いて、($kazu割る余り2の答えが0ならば)5行目の命令を行います。
5行目:「even」を出力します。「."\n"」の部分は文章終わりに改行すると命令しています。
7行目:elseを用いて($kazu割る余り2の答えが0でなければ)8行目の命令を行います。
8行目:「odd」を出力します。
・if(条件){}
()内の条件に当てはまれば、{}内の命令を行います。
elseはifの条件に当てはまらなければ、{}内の命令を行います。
PHP 問題:身長の差
-新しく学んだこと-
・出力に改行を含ませる
問題
A君の身長(a)とB君の身長(b)の差を求めてください。
A君の身長はB君の身長以上に高いものとする。
入力例1 a=180 答え 30
b=150
入力例2 a=201 答え 200
b=1
出力最終行の末尾に改行を入れ、余計な文字、空白を含んではいけません。
プログラミングの前に動きのイメージします。
プログラムにすると
3行目:$shincho(身長差)の箱を用意します。
4行目:入力が続く限り以下の命令を繰り返します。
1行目入力されると、1つ目の箱$stdin_array[0]に文字列を入れます。
2行目が入力されると、2つ目の箱$stdin_array[1]に文字列を入れます。
3行目が~3つ目の箱に入れます。というように行動します。
7行目:2人の身長差を、$stdin_array[0](A君の身長) 引く $stdin_array[1](B君の身長)で計算します。
8行目:$shinchoを表示します。「."\n"」の部分は、文字列の最後に改行するために付けています。
・出力に改行を含ませる
「."\n"」の部分です。ここで重要なのは「" "」で囲む事で、この記号が無いと命令に認識されません。
以上で、問題を終わります。
PHP 問題:分けて余った数
-新しく学んだこと-
・条件付き
・入力の改行くぎり
・割り算の余り
問題
y個のお菓子をx人で分けて、余った個数を求めてください。
分ける人数Xとお菓子の個数yは、改行くぎりで入力されます。
入力例1 x=5 答え 2
y=17
入力例2 x=2 答え 0
y=4
プログラミングの前に動きをイメージします。
プログラムにすると
3行目:余り用の箱を用意します。
4行目:while()は、入力があるかぎりは、以下の命令を繰り返します。
1行目入力されると、1つ目の箱$stdin_array[0]に文字列を入れます。
2行目が入力されると、2つ目の箱$stdin_array[1]に文字列を入れます。
3行目が~3つ目の箱に入れます。というように行動します。
7行目:$stdin_array[1](お菓子の個数)を$stdin_array[0](人数)で割った余りを$nokoriに入れます。「%」が割る余りの計算を表します。
8行目:$nokoriを表示します。
・条件文while()
今回の標準入力は、改行でくぎられた2つの数字になります。
このように縦一列になったデータには、上記のwhile文が使えます。
イメージでは$hito=$stdin_array[0] $okasi=$stdin_array[1]で分類しています。
プログラムの世界では、1つ目の箱は「0」から数え始めます。
以上で、問題を終わります。