基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成24年 春期 基本情報技術者 午後 問09
問09   C言語

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

〔プログラム1の説明〕

 S 社では,通常勤務時間帯( 8 時 30 分〜 18 時)中の各社員の予定を管理している。 関数 allmem_free_slot は,通常勤務時間帯に会議を計画する場合に, 出席して欲しい社員(以下,出席社員という)全員の予定が入っていない時間帯を調べるプログラムである。

(1) S社 では,各社員の予定を 30 分単位の時間帯ごとに図1に示すスケジュール表で管理している。


              図1 スケジュール表

@ スケジュール表は大きさ 19 の整数型配列で,各要素の添字の値は時間帯番号に対応している。

A スケジュール表の各要素には,予定が入っている場合には 0 以外の値が, 予定が入っていない場合には 0 が入る。

(2) 会議時間は 30 分以上であり,開始時刻と終了時刻は時間帯の区切りと一致する。

(3) 関数 allmem_free_slot の引数は次のとおりである。ここで,引数の値に誤りはないものとする。

num    出席社員数
time_tbl  出席社員全員のスケジュール(スケジュール表へのポインタの配列)
slot_num  会議時間( 30 分単位の時間帯数)
free    会議開催の候補時間帯( SLOT 型の配列)

(4) 構造体を使った SLOT 型の定義は次のとおりである。

typedef struct {
  int s_start; /* 開始時間帯番号 */
  int s_num;   /* 時間帯数 */
} SLOT;

(5) 候補時間帯 free には,出席社員全員の予定が入っていない,会議時間以上の連続する時間帯 (以下,可能時間帯という)を全て格納する。最後に格納した要素の次の要素の開始時間帯番号には, −1を格納する。例えば,出席社員5名(社員 A 〜 E )の予定が図2のとおりであった場合, 会議時間が1時間( slot_num=2 )のとき,可能時間帯の一覧は表1になる。


     図2 出席社員全員のスケジュールの例

  表1 可能時間帯の一覧の例

 可能時間帯 開始時間帯番号 時間帯数
  8:30〜10:00 0   3  
 14:00〜15:00 11   2  
 16:30〜18:00 16   3  

(6) 関数 allmem_free_slot で使用している関数 search_free_slot の仕様は次のとおりである。

機能:スケジュール表から,予定が入っていない,時間帯数以上の連続した時間帯を全て探し出し, 空の時間帯に格納する。最後に格納した空き時間帯の要素の次の要素の開始時間帯番号には,−1を格納する。

引数:sch      スケジュール表
   slot_num   時間帯数
   free     空き時間帯数(SLOT 型の配列)

[プログラム1]

#define NUM_DAY 19     /* 1日の時間帯数 */

typedef struct {
    int s_start;       /* 開始時間帯番号 */
    int s_num;         /* 時間帯数 */
} SLOT;
void allmem_free_slot(int, int *[], int, SLOT []);
void search_free_slot(int [], int, SLOT []);

void allmem_free_slot(int num, int *time_tbl[], int slot_num,
                      SLOT free[]) {
    int sch[NUM_DAY], i, j;

    for (i= 0; i < NUM_DAY; i++) {
        sch[i] = ;
        for (j = 1; j < num; j++) {
            if (time_tbl[j][i] != 0) {
                sch[i] = 1;
            }
        }
    }
    search_free_slot(sch, slot_num, free);
}

void search_free_slot(int sch[], int slot_num, SLOT free[]) {
    int cnt = 0, free_num = 0, i;

    for (i = 0, i < NUM_DAY; i++) {
        if (sch[i] != 0){
            if (cnt >= slot_num) {
               free[free_num].s_start = ;
               free[free_num].s_num   = cnt;
               free_num++;
            }
            ;
        } else {
            cnt++;
        }
    }
    if (  ) {
        free[free_num].s_start = NUM_DAY - cnt;
        free[free_num].s_num   = cnt;
        free_num++;
    }
    free[free_num].s_start = -1;
}

設問1 プログラム1中の に入れる正しい答えを, 解答群の中から選べ。

a に関する解答群

ア 0     イ 1     ウ time_tbl [0][0]

エ time_tbl[0][i]

b に関する解答群

ア i     イ i - cnt     ウ i - cnt + 1

エ i - cnt - 1     オ NUM_DAY - cnt

c に関する解答群

ア cnt = 0     イ cnt++     ウ cnt--

エ free_num = 0     オ free_num++     カ free_num--

d に関する解答群

ア cnt == 0     イ cnt > 0     ウ cnt >= slot_num

エ cnt < slot_num     オ free_num == 0     カ free_num > 0

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

基本情報技術者試験


設問2 出席社員が増え,出席社員全員での会議の計画ができない(可能時間帯がない)場合がでてきた。 そこで,出席社員を出席が必須の社員(以下,必須出席社員という)とそれ以外の社員 (以下,任意出席社員という)に分け,必須出席社員全員が出席可能な時間帯で会議の計画をすることにした。 さらに,任意出席社員について順位付けを行い,順位の高い方から最多の社員が出席可能な時間帯に絞込 みを行うことにした。この条件で会議が計画できる時間帯を調べるプログラムを作成した。 作成したプログラム中の に入れる正しい答えを,解答群の中から選べ。 ここで, には,設問1の正しい答えが入っているものとする。

〔プログラム2の説明〕

(1) 関数 allmem_free_slot の引数は次のとおりである。ここで,引数の値に誤りはないものとする。

num     出席社員数
must_num  必須出席社員数
time_tbl  出席社員全員のスケジュール(スケジュール表へのポインタの配列)
slot_num  会議時間( 30 分単位の時間帯数)
free    会議開催の候補時間帯( SLOT 型の配列)

@ 必須出席社員のスケジュール表へのポインタは,time_tbl の先頭から人数分が格納されている。

A 任意出席社員のスケジュール表へのポインタは,time_tbl の必須出席社員の スケジュールに続けて,順位の高い方から順に格納されている。

(2) 候補時間帯 free には,必須出席社員全員が出席可能な時間帯の中で, 任意出席社員の順位の高い方から最多の社員が出席可能な時間帯を全て格納する。 最後に格納した要素の次の要素の開始時間帯番号には,−1を格納する。

〔プログラム2〕

#define NUM_DAY 19     /* 1日の時間帯数 */

typedef struct {
    int s_start;       /* 開始時間帯番号 */
    int s_num;         /* 時間帯数 */
} SLOT;

void maxmem_free_slot(int, int, int *[], int, SLOT []);
void search_free_slot(int [], int, SLOT []);

void maxmem_free_slot(int num, int must_num, int *time_tbl[],
                      int slot_num, SLOT free[]) {
    int sch[NUM_DAY], i, j, k;
    SLOT wk_free[2][NUM_DAY + 1];

    /* 必須出席社員全員が出席可能な時間帯を探し出す */
    for (i= 0; i < NUM_DAY; i++) {
        sch[i] = ;
        for ( ; j++) {
            if (time_tbl[j][i] != 0) {
                sch[i] = 1;
            }
        }
    }
    search_free_slot(sch, slot_num, wk_free[0]);

    /* 任意出席社員の順位の高い方から
       最多の社員が出席可能な時間帯に絞り込む */

    for (j = must_num; j < num; j++) {
        for (i = 0; i < NUM_DAY; i++) {
            if (time_tbl[j][i] != 0 ) {
               sch[i] = 1;
            }
        }
        search_free_slot(sch, slot_num, wk_free[1]);
        if (  ) {
            break;
        }
        k = 0;
        do {
           wk_free[0][k] = wk_free[1][k];
        } while (wk_free[1][k++].s_start != -1);
    }

    /* 候補時間帯を格納する */
    k = 0;
    do {
        free[k] = wk_free[0][k];
    } while (wk_free[0][k++].s_start != -1);
}

e に関する解答群

ア j = 1; j < must_num     イ j = 1; j < num

ウ j = 1; j < num - must_num     エ j = must_num; j < num

オ j = num - must_num; j < num

f に関する解答群

ア wk_free[1][0].snum == 0

イ wk_free[1][0].snum == -1

ウ wk_free[1][0].snum > slot_num

エ wk_free[1][0].start == 0

オ wk_free[1][0].start == -1

カ wk_free[1][0].start > slot_num

解答 e ←クリックすると正解が表示されます

解答 f ←クリックすると正解が表示されます


[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]