Copyright (C) IOI日本委員会 1995. All rights reserved.


問題3.

 n 種類の品物を m 台のトラックで運ぶことを考える。 品物は各種類ともに p 個ずつある。i 番目のトラックは vi 個までの 品物を運ぶことができる。ただし、それぞれのトラックは同じ種類の 品物を x 個までしか運べないとする。
 すべての品物を運ぶ運送計画を立てるプログラムを作りたい。 運送計画では、それぞれのトラックは1度だけ使うが、 品物を載せないトラックがあってもよく(その場合、そのトラックに載せる 品物の個数はすべて0とする)、複数の計画が作れる場合でも最初に求めた もの1つを出力すればよい。ただし、すべての品物を運ぶ計画が存在しない ときは、``解なし''と出力する。
 データはASCIIテキストファイル INPUT.TXT から入力する。 データは1組だけあり、次のような形式で書かれている:

n p x
m
v1 v2 ... vm

 求めた計画は、次のような形式でASCIIテキストファイル OUTPUT.TXT に 出力する:

個数11 個数12 ... 個数1n
個数21 個数22 ... 個数2n
...
個数m1 個数m2 ... 個数mn

 ただし、個数ij は i 番目のトラックへ載せる j 番目の品物の 個数である。

入力例1

7 4 2
5
8 8 5 4 4
出力例1
 2 2 2 2 0 0 0
 2 2 2 2 0 0 0
 0 0 0 0 2 2 1
 0 0 0 0 2 1 1
 0 0 0 0 0 1 2

入力例2

3 6 2
4
7 5 4 2
出力例2

解なし

 下記の3つの言語で書かれたプログラムの一つを完成させなさい。 空欄には、運送計画を求める関数(空欄(a)には関数呼出し、空欄(b)には 関数の定義)を書き入れなさい。関数名と引数は適当に決めること。 関数の仕様は、運送計画があるときは true、ないときは false を 返し、運送計画自体は配列変数 plan へ代入することとする。 用いたアルゴリズムがどのようなものであるか、その要点を述べ(プログラム 内にコメントとして書いてよい)、それに基づいたプログラムを書きなさい。


Cプログラム(3)

#include <stdio.h>

typedef enum { false, true } boolean;

#define max_n 100+1
#define max_m 100+1

int n;  /* 品物の種類 */
int p;  /* 品物の個数 */
int x;  /* 同じ種類の品物はx個まで */
int m;  /* トラックの台数 */
int plan[max_m][max_n];
 /* plan[i][j] (i=1..m, j=1..n) i番目のトラックに積まれているj番目の品物の個数 */
 /* plan[i][0] i番目のトラックに積める品物の個数 */
 /* plan[0][j] j番目の品物の残り個数 */

void main()
{
   FILE *f; int i,j;

   f = fopen("INPUT.TXT", "r");
   fscanf(f, "%d %d %d", &n,&p,&x);
   fscanf(f, "%d", &m);
   for (i = 1; i <= m; i++) for (j = 1; j <= n; j++) plan[i][j] = 0;
   for (i = 1; i <= n; i++) plan[0][i] = p;
   for (i = 1; i <= m; i++) fscanf(f, "%d", &plan[i][0]);
   fclose(f);

   f = fopen("OUTPUT.TXT", "w");
        ---------------------
  if ( |         (a)         | )
        ---------------------
      for (i = 1; i <= m; i++) {
         for (j = 1; j <= n; j++) fprintf(f, " %d", plan[i][j]);
         fprintf(f, "\n");
      }
   else fprintf(f, "解なし");
   fclose(f);
}

   -----------------------------------------------------------------------
  |                                                                       |
  |                                                                       |
  |                       空欄(b):関数の定義                            |
  |                                                                       |
  |                                                                       |
   -----------------------------------------------------------------------


BASICプログラム(3)

DEFINT A-Z
DECLARE FUNCTION solve (level AS INTEGER)
CONST false = 0, true = -1
CONST maxN = 100, maxM = 100
DIM SHARED n AS INTEGER  ' 品物の種類
DIM SHARED p AS INTEGER  ' 品物の個数
DIM SHARED x AS INTEGER  ' 同じ種類の品物はx個まで
DIM SHARED m AS INTEGER  ' トラックの台数
DIM SHARED plan (maxN, maxM) AS INTEGER
  ' plan(i,j) (i=1..m, j=1..n) i番目のトラックに積まれているj番目の品物の個数
  ' plan(i,0) i番目のトラックに積める品物の個数
  ' plan(0,j) j番目の品物の残り個数

   OPEN "INPUT.TXT" FOR INPUT AS #1
   INPUT #1, n, p, x
   INPUT #1, m
   FOR i = 1 TO m: FOR j = 1 TO n: plan (i, j) = 0: NEXT j: NEXT i
   FOR i = 1 TO n: plan (0, i) = p: NEXT i
   FOR i = 1 TO m: INPUT #1, plan (i, 0): NEXT i
   CLOSE #1

   OPEN "OUTPUT.TXT" FOR OUTPUT AS #1
       ------------------------------
   IF |           (a)                | THEN
       ------------------------------
      FOR i = 1 TO m
         FOR j = 1 TO n: PRINT #1, plan (i, j); : NEXT j
         PRINT #1,
      NEXT i
   ELSE PRINT #1, "解なし"
   END IF
   CLOSE #1
END

   -----------------------------------------------------------------------
  |                                                                       |
  |                                                                       |
  |                       空欄(b):関数の定義                           |
  |                                                                       |
  |                                                                       |
   -----------------------------------------------------------------------


BASICプログラム(3)

program problem3;

   const max_n = 100;
         max_m = 100;
   var   n: integer;  { 品物の種類 }
         p: integer;  { 品物の個数 }
         x: integer;  { 同じ種類の品物はx個まで }
         m: integer;  { トラックの台数 }
         plan: array[0..max_m,0..max_n] of integer;
       { plan[i][j]  (i=1..m, j=1..n) i番目のトラックに積まれている
                                      j番目の品物の個数 }
       { plan[i][0]  i番目のトラックに積める品物の個数 }
       { plan[0][j]  j番目の品物の残り個数 }

     -----------------------------------------------------------------------
    |                                                                       |
    |                                                                       |
    |                       空欄(b):関数の定義                           |
    |                                                                       |
    |                                                                       |
     -----------------------------------------------------------------------

var f: text; i,j: integer;

begin
   assign(f, 'INPUT.TXT'); reset(f);
   readln(f, n, p, x);
   readln(f, m);
   for i := 1 to m do for j := 1 to n do plan[i][j] := 0;
   for i := 1 to n do plan[0][i] := p;
   for i := 1 to m do read(f, plan[i][0]);
   close(f);

   assign(f, 'OUTPUT.TXT'); rewrite(f);
       ------------------
   if |        (a)       | then
       ------------------
      for i := 1 to m do begin
         for j := 1 to n do write(f, ' ', plan[i][j]);
         writeln(f);
      end
   else writeln(f, '解なし');
   close(f);
end.


JOIホームページへ戻る

JOI'95へ戻る