戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

基本情報技術者 2009年 秋期 午後 問11


次のJavaプログラムの説明及びプログラムを読んで、設問1,2に答えよ。

〔プログラムの説明〕  携帯電話の利用状況に対して、最も安価な料金プラン(割引サービスを含む)を提示するプログラムである。1か月の料金は、基本料金、通話料金及びパケット料金からなる。パケット料金にはオプションの割引サービスがある。  表1に料金プラン、表2にパケット料金の割引サービス、表3にテスト用の利用状況を示す。  なお、パケット料金を計算するとき、パケット数は100パケット単位に切り上げる。
基本情報技術者試験(平成21年 午後 問11 表1)
基本情報技術者試験(平成21年 午後 問11 表2)
基本情報技術者試験(平成21年 午後 問11 表3)
(1) クラスCellPhonePlanは、料金プランを表す。メソッドcalculateChargeは、引数で渡された利用状況に対する料金を返す。 (2) クラスCallingPlanは、通話料金を計算するクラスである。メソッドcalculateChargeは、引数で渡された通話時間(分単位に切上げ)に対する料金を返す。 (3) インタフェースPacketPlanは、パケット料金を計算するためのインタフェースである。メソッドcalculateChargeは、引数で渡されたパケット数に対する料金を返す。 (4) クラスMeasuredは、従量制のパケット料金(割引サービスなしの場合)を表す。 (5) クラスTieredは、パケット料金の割引サービスS1を表す。 (6) クラスCellPhonePlannerは、利用状況に対して、最も安価な料金プラン(割引サービスを含む)を提示する。メソッドgetRecommendedPlanは、与えられた利用状況に対して、最も安価な料金プラン(割引サービスを含む)を返す。メソッドmainは、テスト用のメインプログラムである。  プログラムの実行結果を図に示す。
基本情報技術者試験(平成21年 午後 問11 図)
基本情報技術者試験(平成21年 午後 問11 プログラム1)
基本情報技術者試験(平成21年 午後 問11 プログラム2)
基本情報技術者試験(平成21年 午後 問11 プログラム3)
基本情報技術者試験(平成21年 午後 問11 プログラム4)
基本情報技術者試験(平成21年 午後 問11 プログラム5)
基本情報技術者試験(平成21年 午後 問11 プログラム6)

設問1:

問題文を見る
 プログラム中のに入れる正しい答えを、解答群の中から選べ。   aに関する解答群  ア:callingRate * minutes  イ:callingRate * minutes - included  ウ:included  エ:included - callingRate * minutes   bに関する解答群  ア:callingCharge < 0  イ:callingCharge < included  ウ:callingCharge > 0  エ:callingCharge > included   cに関する解答群  ア:extends CellPhonePlan  イ:extends PacketPlan  ウ:implements CellPhonePlan  エ:implements PacketPlan   dに関する解答群  ア:allowance + 99  イ:packets + 99  ウ:packets + allowance + 99  エ:packets - allowance + 99   e, fに関する解答群  ア:0  イ:Integer.MIN_VALUE  ウ:Integer.MAX_VALUE  エ:cellPhonePlan.calculateCharge(minutes, packets)  オ:recommended.calculateCharge(minutes, packets)

模範解答

a:イ、b:ア、c:エ、d:エ、e:ウ、f:エ

解説

解答の導き方

このプログラムでは、通話料金とパケット料金をそれぞれ計算し、料金プランの組合せの中から最も安いものを選びます。空欄は、料金計算の式とプログラムの流れを順に追うと判断できます。
通話料金の計算:a、b
表1では、基本料金に「無料通話分」が含まれています。したがって、通話時間に応じて計算した通話料金のうち、無料通話分を超えた金額だけを追加料金にします。
通話時間を 分、1分当たりの通話料金を 円、無料通話分を 円とすると、無料通話分を差し引いた金額は次の式です。
これが負の値なら、通話料金が無料通話分に収まっているということです。その場合、追加料金は 円にします。よって、aには「callingRate * minutes - included」、bには「callingCharge < 0」が入ります。
例えば、料金プランAで30分通話した場合、通話料金は 円です。無料通話分の1,000円を引くと200円なので、通話料金は基本料金2,000円に200円を加えた2,200円です。
料金プランBで30分通話した場合は、 円です。負の値なので、追加の通話料金は0円となり、通話料金は基本料金の3,000円です。
PacketPlanを実装する:c
プログラム3では、PacketPlanが「calculateCharge」などのメソッドを定めています。このように、クラスに必要なメソッドの形を示すものをインタフェースといいます。
MeasuredとTieredは、どちらもパケット料金を計算するクラスです。両方がPacketPlanに定められたメソッドを用意するため、クラスの宣言にはインタフェースを実装することを表す「implements」を使います。したがって、cには「implements PacketPlan」が入ります。「extends」はクラスを継承するときに使うもので、この場合には当てはまりません。
従量制のパケット料金
問題文には「パケット数は100パケット単位に切り上げる」とあります。Measuredでは、100パケットごとの料金に、切り上げた単位数を掛けています。
プログラム中の「(packets + 99) / 100」は、パケット数を100で割ったときの端数を切り上げる式です。例えば、1,000パケットなら10単位、1,001パケットなら11単位になります。1,000パケットの料金は、100パケット当たり20円なので、 円です。
割引サービスの料金計算:d
Tieredでは、まずサービス料金の1,000円を料金に設定します。さらに、パケット数がallowanceを超えた場合だけ、超えた分の料金を加えます。
超過分は です。この超過分を100パケット単位で切り上げるため、dには「packets - allowance + 99」が入ります。式全体では、超過分の単位数を次のように計算しています。
この計算が行われるのは、パケット数がallowanceを超えた場合だけです。S1ではallowanceが10,000パケットなので、10,000パケットまではサービス料金の1,000円だけで、超えた分には100パケット当たり8円が加算されます。
最も安いプランを選ぶ:e、f
プログラムは、複数の料金プランを順に調べ、現在の最安料金より安いものがあれば、そのプランを最安候補として記録します。
まだ1つも料金を調べていない段階では、minChargeを非常に大きな値にしておきます。そうすれば、最初に計算した料金が必ずminCharge以下になり、最初のプランが候補に記録されます。JavaのInteger.MAX_VALUEは整数として扱える最大値なので、eには「Integer.MAX_VALUE」が入ります。
繰返し処理の中では、今調べているプランの料金を計算します。対象のプランはループ変数cellPhonePlanが表しているため、fには「cellPhonePlan.calculateCharge(minutes, packets)」が入ります。計算した料金がminCharge以下なら、そのプランをrecommendedに記録し、minChargeも更新します。
テスト用の利用状況で確認する
表3の各利用状況について、4種類の料金プランの組合せを比較すると、次のようになります。料金プランの組合せは、AまたはBと、割引なしまたはS1との組合せです。
通話時間(分)パケット数A(割引なし)A S1B(割引なし)B S1最も安い組合せ
301,0002,400円3,200円3,200円4,000円A
3010,0004,200円3,200円5,000円4,000円A S1
3001,00013,200円14,000円10,200円11,000円B
30010,00015,000円14,000円12,000円11,000円B S1
例えば、通話時間が30分、パケット数が1,000の場合、Aの通話料金は2,200円、従量制のパケット料金は200円です。合計は2,400円となり、ほかの組合せより安くなります。
一方、通話時間が30分、パケット数が10,000の場合、A S1の料金は、Aの通話料金2,200円とS1のサービス料金1,000円を合わせた3,200円です。割引なしのパケット料金は2,000円かかるため、A S1の方が安くなります。
通話時間が300分の場合、Aの通話料金は 円で、基本料金と合わせて13,000円です。Bは 円で、基本料金と合わせて10,000円です。通話時間が長いとBの方が安くなります。

誤りやすいポイント

  • 無料通話分は、通話時間から差し引く時間ではなく、基本料金に含まれている金額です。そのため、通話料金の金額からincludedを引きます。
  • 通話料金の追加分が負の値になったときは、0円にします。負の料金を基本料金から差し引くわけではありません。
  • S1の割引対象は、パケット数全体ではなくallowanceを超えた分です。超過分を計算する式では、packetsからallowanceを引きます。
  • 最安料金を探すとき、minChargeを0で初期化すると、通常の料金が0円以下でない限り候補が選ばれません。最初の候補を確実に記録できるよう、大きな値で初期化します。
  • 料金を比べるのは、料金プランAとBだけではありません。通話プランとパケットプランの組合せをすべて調べます。

FAQ

Q: S1の料金は、パケット数が10,000のときも1,000円ですか?
A: はい。表2では10,000パケットまでは無料とされているため、パケット料金はかかりません。ただし、S1のサービス料金1,000円はかかります。
Q: 料金が同じプランがあった場合、どれが選ばれますか?
A: 条件が「charge <= minCharge」なので、同じ料金の場合も後から調べたプランが候補に記録されます。このテスト用の利用状況では、最安のプランが同額になるケースはありません。
Q: 「(packets + 99) / 100」で切り上げられるのはなぜですか?
A: 100で割る前に99を足すことで、100で割り切れない分があれば、商が次の整数になります。例えば、1,001パケットでは「(1,001 + 99) / 100」が11となり、必要な100パケット単位数を切り上げられます。

関連キーワード: インタフェース、実装、整数除算、切上げ、最小値探索

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

 パケット通信を大量に行う人を対象として、S1の内容を変更したパケット料金割引サービスS2を追加することにした。表4にサービスの内容、プログラム7にS2を表すクラスを示す。プログラム7中のに入れる正しい答えを、解答群の中から選べ。
基本情報技術者試験(平成21年 午後 問11 表4)
基本情報技術者試験(平成21年 午後 問11 プログラム7)
gに関する解答群  ア:extends PacketPlan  イ:extends Tiered  ウ:implements PacketPlan  エ:implements Tiered   h, iに関する解答群  ア:0  イ:allowance  ウ:basicCharge  エ:basicCharge + maxCharge  オ:maxCharge  カ:super.calculateCharge(packets)  キ:this.calculateCharge(packets)

模範解答

g:イ、h:カ、i:オ

解説

解答の導き方

この問題では、既存の割引サービスの計算を利用しながら、パケット料金に上限を設けるクラスを作ります。
  1. g:どのクラスを引き継ぐか
    クラスは、データや処理をまとめる設計図です。既存のクラスの性質を引き継いで、新しい処理を加える仕組みを「継承」といいます。
    既存のTieredは、基本料金、無料となるパケット数、超過分の料金を使って計算します。S2もこの計算方法を使い、さらに料金の上限を設けるサービスです。そのため、TieredBoundedはTieredを継承します。クラスの継承を表す書き方はextendsなので、gにはextends Tieredが入ります。
    また、プログラム7のコンストラクタ(オブジェクトを作るときに初期化する処理)には、super(name, basicCharge, allowance, packetRate)があります。superは継承元のクラスを指すため、継承元はこの引数を受け取るTieredだと分かります。
    PacketPlanは、必要なメソッドを定めるインタフェース(クラスに実装してほしい処理の約束)です。インタフェースを実装するときはimplementsを使います。一方、Tieredはクラスなので、ここではimplementsではなくextendsを使います。
  2. h:上限を適用する前の料金をどう計算するか
    S2は、まずTieredと同じ方法で料金を計算し、その結果が上限を超えたときに上限額へ置き換えます。
    そのため、hには継承元TieredのcalculateChargeを呼び出すsuper.calculateCharge(packets)が入ります。これなら、既存の計算処理をそのまま利用できます。
    this.calculateCharge(packets)を使うと、今作っているTieredBoundedのcalculateChargeをもう一度呼び出します。同じ処理を繰り返してしまうため、料金を計算できません。
  3. i:比較する上限額はどれか
    表4では、50,000パケットを超えた場合も料金は一律5,000円です。Tieredの計算で求めた料金が上限額より大きいとき、その料金を上限額に置き換える必要があります。
    S2では、50,000パケットのときに、基本料金1,000円に超過分の料金4,000円を足すと、合計は5,000円になります。
    したがって、上限額を表すmaxChargeと比較します。条件式はcharge > maxChargeとなり、iにはmaxChargeが入ります。

誤りやすいポイント

  • gでimplementsを選ぶこと
    implementsはインタフェースを実装するときに使います。TieredBoundedが引き継ぐ相手はクラスのTieredなので、extendsを選びます。
  • hでthis.calculateCharge(packets)を選ぶこと
    thisは、今処理しているオブジェクト自身を指します。同じメソッドを自分自身から呼ぶため、計算が終わらず繰り返されます。継承元の計算を使うにはsuperを指定します。
  • iでbasicChargeを選ぶこと
    basicChargeはサービスの基本料金であり、料金の上限ではありません。S2では超過分も含めた料金全体を5,000円までにするため、比較するのはmaxChargeです。

FAQ

Q: S2でTieredの計算を使うのはなぜですか?
A: 無料となるパケット数や超過分の料金計算は既存のTieredで行い、S2で追加する上限処理だけをTieredBoundedに加えるためです。
Q: 料金がmaxChargeと同じ場合も、上限額に置き換えますか?
A: 条件はcharge > maxChargeです。料金が上限額と同じなら、そのまま返しても上限額に置き換えても結果は同じです。
Q: パケット数を100パケット単位に切り上げる処理は、どこで行いますか?
A: Tieredの料金計算で行います。TieredBoundedはその計算結果を受け取り、上限を超えた場合だけ料金を抑えます。

関連キーワード: 継承、インタフェース、メソッド呼出し、上限処理、切上げ計算

解説を読んでも分からないところは、AIに質問できます。 この問題の本文と解説をふまえて答えます。

この設問をAIに質問する

クイズモードで開きます(AIへの質問は無料の会員登録で使えます)

戦国ITクイズ機能

\ せっかくなら /

基本情報技術者を
クイズ形式で学習しませんか?

クイズ画面へ遷移する→

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について