| 网站首页 | 学校介绍 | 德育工作 | 家长学校 | 教学教研 | 信息技术 | 书香飘逸 | 资源下载 | 靓图欣赏 | 雁过留声 | 语文 | 
最新公告:     已所不欲,勿施于人,已之所欲,施之于人!  [adminit  2007年4月19日]            生命如流水,只有在他的急流与奔向前去的时候,才美丽,才有意义。 ——张闻天  [旗峰中学  2006年7月8日]            不要让忧愁压在你的心头,也不要让犹豫缠住你的脚步,满天的阴霾终会被风吹散,而晴朗的天空就是你无比辉煌的前程。只有在遭受痛苦经历时,仍然能笑,仍然能乐观的生活的人,才称得起是真正坚强的人。生活是一面镜子,你对它笑,他就对你笑;你对它哭,他也对你哭。  [旗峰中学  2006年7月8日]            勤学如春起之苗,不见其增,日有所长;辍学如磨刀之石,不见其损,日有所亏。  [旗峰中学  2005年11月3日]            志不强者智不达,言不信者行不果。  [旗峰中学  2005年11月3日]        
您现在的位置: 旗峰中学校园网 >> 信息技术 >> 信息奥赛 >> 奥赛题库 >> 文章正文
专题栏目
更多内容
最新推荐 更多内容
相关文章
第三届NOC“电脑动画”初
第三届NOC“主题网页设计
第三届NOC“主题网页设计
全国青少年网络文明公约
第十一届青少年信息学联
2005年南海区青少年信息
天津市青少年信息学(计算
进制互化问题
逻辑判断问题
八皇后问题程序及注解
更多内容
第二届选拔赛试题           ★★★
第二届选拔赛试题
作者:佚名 文章来源:本站原创 点击数: 更新时间:2005-6-1 13:44:17

. 钱币系统问题( 30分 )

 

    某钱币系统由 k (k≤20) 种硬币组成, 币值依次为 a[1],a[2],...,a[k], 其中 a[i] (i=1,2,...,k) 为互不相同的正整数, 且依降序排列, a[1]≤200. 给定某整数币值 n(n≤3000), 要求用最少枚数的硬币表示这个币值.

   

    输入: 用文件输入已知数据, 格式为:

      第 1 行: k (硬币种数)

      第 2 行: a[1] a[2] ... a[k] (各币值用空格隔开,已按降序排列好)

      第 3 行: n (给定的币值)

 (参看文件 EXAM1.TXT).

   

    输出: 直接在屏幕上输出结果. 如果该钱币系统无法表示币值 n,应输出'No', 否则按以下格式输出:

      第 1 行: 最少钱币枚数 r.

      第 2 行: 输出若干形如 m*n 的表达式, m 为币值, n为使用该币值的枚数. 各式第 2 个因子之和应等于 r, 各式乘积之和应等于 n.

    例: 设 (a[1],a[2],a[3])=(5,2,1),  n=12,  则应输出

       3

       5*2  2*1.

 

program coi962_1; { 钱币系统问题, Write by Li Xuewu }

  type arr10=array [1..10] of integer;

  var

    a,b,b2: arr10;

    i,j,k,n,r,r1: integer;   file1: string[20];

    text1: text;   gree: boolean;

{贪心法子程序}

procedure greedy(n,k:integer; var b2:arr10; var r:integer);

  var j:integer;

begin

  r:=0;

  for j:=1 to k do

    begin

      b2[j]:=n div a[j];

      r:=r+b2[j];  n:=n-b2[j]*a[j];

    end;

  if n>0 then  r:=3000;

end;

{输出结果}

procedure result(r:integer);

  var i:integer;

begin

  if r=3000

    then writeln('No solution!')

  else

    begin

      writeln(r:4);

      for i:=1 to k do

        if  b[i]>0 then  write(a[i]:3,'*',b[i],'  ');

      writeln

    end;

end;

{递归回溯子程序}

procedure find1(w,t:integer;var b2:arr10);

  var i,j,m,w1:integer;

begin{*}

  m:=w div a[t];

  for j:=0 to m do

    begin{**}

      w1:=w;

      if t=1 then r:=0;

      w1:=w1-j*a[t];  r:=r+j;  b2[t]:=j;

      if w1=0 then for i:=t+1 to k do b2[i]:=0;

      if (w1>0)and(r<r1)and(t<k) then find1(w1,t+1,b2);

      if (w1=0)and(r<r1) then

        begin

          r1:=r;

          for i:=1 to k do b[i]:=b2[i];

        end;

      r:=r-j;

    end;{**}

end;{*}

begin {main}

  writeln('input filename:');   readln(file1);

  assign(text1,file1);   reset(text1);

  readln(text1,k);

  r:=0;  r1:=0;

  for i:=1 to k do b[i]:=0;

  b2:=b;

  writeln('Money system:');

  for i:=1 to k do

    begin  read(text1,a[i]); write(a[i]:4); end;

  readln(text1); writeln;

  readln(text1,n); writeln('The number of Money:',n:5);

  close(text1);

  gree:=true;

  for i:=1 to k-1 do if a[i]<(2*a[i+1]) then gree:=false;

  if a[k]>1 then gree:=false;

  r1:=3000;

  greedy(n,k,b,r1);

  if gree  then  result(r1)

    else  begin  find1(n,1,b2); result(r1)  end;

end.

 

. 省刻度尺问题( 35分 )

 

    给定长度为 L 的直尺, L 为整数,且L≤40. 为了能一次直接量出  1,2,...,L 的各种长度, 该尺内部至少要有多少条刻度 ? 请输出最少刻度数(不含两端点)及每个刻度的位置. 测量长度时可利用两端点, 其位置分别为 0, L.

   

    输入: 由键盘输入 L.

    输出: 用文本文件按以下格式输出结果(文件名: ANS2.TXT):

      第 1 行: S ( 最少刻度数 )

      第 2 行: 尺内 S 个刻度的位置

      第 3 行至第 L+2 行: 每行输出 3 个用空格隔开的整数 t m n, 其中 1≤t≤L 为要测量的各长度, m,n 依次为该长度的起止刻度 (m<n).

    例: 如果 L=6, 则一个正确的输出是:

       2

       1 4                    提示:  (1) 最少刻度数 S 应满足:

       1 0 1                     C[S+2,2]=(S+2)*(S+1)/2≥L.

       2 4 6                         (2) 除两端点外, 第一个刻度可取为

       3 1 4                     A[1]=1, 第二个刻度可在 2, L-2, L-1 这

       4 0 4                     三个数中选取.

       5 1 6

       6 0 6

 

program coi962_2; { 省刻度尺问题 , Write by Li Xuewu }

  label 10;

  type arr40=array [0..40]of byte;

  var  a,b,c,d:arr40;

       i,j, k,kz,r,m,t1,t2:byte;

       done: boolean;

procedure result;

  var  file1:string[20];

       text2:text;

       i,j,w:integer;

begin

  writeln('enter filename for output:');

  readln (file1);

  assign(text2,file1);   rewrite(text2);  writeln(k:2);

  for i:=1 to k do  write(a[i]:4);

  writeln;

  for i:=1 to m do writeln(i:2, c[i]:4,d[i]:4);

  writeln(text2,k:2);

  for i:=1 to k do  write(text2,a[i]:4);

  writeln(text2);

  for i:=1 to m do writeln(text2,i:2, c[i]:4,d[i]:4);

  close(text2);

  done:=true;

  halt;

end;

procedure init1;

  var i:integer;

begin

  for i:=0 to 40 do b[i]:=0;  c:=b; d:=b;

  for i:=2 to k do a[i]:=0;

  a[0]:=0;  a[k+1]:=m;   a[1]:=1;

end;

procedure find2(r,t1,t2:integer);

  var i,j,j2,v1,v2,t,t3,t4,temp:integer;

begin {1}

  for i:=t1 to t2 do

    begin {2}

      a[r]:=i;

      if (r<k) and (i<t2) then

        begin  t3:=i+1;  find2(r+1,t3,t2); end;

      if r=k then

        begin{3}

          if ((kz=1)or(kz=3)) and (k>2) then

            begin

              temp:=a[2];

              for j:=2 to k-1 do a[j]:=a[j+1];

              a[k]:=temp;

            end;

          for j:=1 to m do b[j]:=0;

          for j:=0 to k  do

          for j2:=j+1 to k+1 do

            begin

              t:=a[j2]-a[j];

              if b[t]=0 then

                begin

                  b[t]:=1; c[t]:=a[j]; d[t]:=a[j2];

                end;

            end;

          done:=true;  j:=0;

          repeat j:=j+1 until (b[j]=0)or(j>m);

          if j<=m then done:=false;

          if done then result;

        end;{3}

    end; {2}

end; {1}

begin{main}

  writeln('inptu L:(L<=40 and L>3)');  readln(m);

  k:=0;

  repeat k:=k+1 until ((k+2)*(k+1) div 2) >= m;

  10: init1;

  for kz:=1 to 3 do

    case kz of

      1: begin{*}

           a[2]:=m-2;

           if k=2

             then find2(2,a[2],a[2])

             else

               begin

                 r:=3; t1:=2;  t2:=m-3;

                 find2(r,t1,t2);

               end;

         end;{*}

      2: begin{**}

           a[2]:=2;

           r:=3; t1:=3;  t2:=m-1;

           if t2<t1 then t2:=t1;

           find2(r,t1,t2);

         end;{**}

      3: begin{***}

           a[2]:=m-1;

           r:=3; t1:=2; t2:=m-2;

           if t2<t1 then t2:=t1;

           find2(r,t1,t2);

         end;{***}

    end;{case}

  k:=k+1;  goto 10;

end.

 

. 卡车更新问题( 35分 )

  

    某人购置了一辆新卡车, 从事个体运输业务. 给定以下各有关数据:   

    R[t], t=1,2,...,k, 表示已使用过 t 年的卡车, 再工作一年所得的运费, 它随 t 的增加而减少, k (k≤20) 年后卡车已无使用价值.

    U[t], t=1,...,k, 表示已使用过 t 年的卡车, 再工作一年所需的维修费, 它随 t 的增加而增加. 

    C[t], t=1,2,...,k, 表示已使用过 t 年的旧卡车, 卖掉旧车, 买进新车, 所需的净费用, 它随 t 的增加而增加. 以上各数据均为实型, 单位为"万元".

    设某卡车已使用过 t 年,

    ① 如果继续使用, 则第 t+1 年回收额为 R[t]-U[t],

    ② 如果卖掉旧车,买进新车, 则 第 t+1 年回收额为 R[0]-U[0]-C[t] .

    该运输户从某年初购车日起,计划工作 N (N<=20) 年, N 年后不论车的状态如何,不再工作. 为使这 N 年的总回收额最大, 应在哪些年更新旧车?  假定在这 N 年内, 运输户每年只用一辆车, 而且以上各种费用均不改变.

   

    输入: 用文件输入已知数据, 格式为:

      第 1 行: N (运输户工作年限)

      第 2 行: k (卡车最大使用年限, k≤20 )

      第 3 行: R[0] R[1] ... R[k]

      第 4 行: U[0] U[1] ... U[k]

      第 5 行: C[0] C[1] ... C[k]

   

    输出: 用文本文件按以下格式输出结果(文件名: ANS3.TXT):

      第 1 行: W ( N 年总回收额 )

      第 2--N+1 行: 每行输出 3 个数据:

         年序号     ( 从 1 到 N 按升序输出 );

         是否更新   ( 当年如果更新,输出 1, 否则输出 0);

         当年回收额 ( N 年回收总额应等于 W ).

   

    例: 设给定以下数据:

      N=4,  k=5,

         i:   0    1    2    3    4    5

      R[i]:   8    7    6    5    4    2

      U[i]:  0.5   1    2    3    4    5

      C[i]:   0    2    3    5    8   10

    则正确输出应是

      24.5

      1    0   7.5

      2    1   5.5

      3    1   5.5

      4    0   6.0

 

program coi962_3; {卡车更新问题}

  type arr20=array[0..20] of real;

  var rr,uu,cc,d,e:arr20;

      f:array [0..22,0..21] of real;

      g:array [0..22,0..21] of integer;

      i,j,k,k2,n,t:integer;

      file1:string[20];   p,q:real;

      text2,text3:text;

procedure init;

  var i:integer;

begin

  writeln('Input filename:');

  readln(file1);

  assign(text2,file1);  reset(text2);

  readln(text2,n);  readln(text2,k);

  for i:=0 to k do read(text2,rr[i]);  readln(text2);

  for i:=0 to k do read(text2,uu[i]);  readln(text2);

  for i:=0 to k do read(text2,cc[i]);  readln(text2);

  close(text2);

  for i:=0 to k do

    begin d[i]:=rr[i]-uu[i];  e[i]:=d[0]-cc[i];  end;

end;

procedure result3;

  var i:integer;

begin

  writeln('enter filename for output:');

  readln(file1);

  assign(text3,file1);   rewrite(text3);

  writeln(text3,f[1,1]:8:3);

  writeln(text3,' 1  0', e[0]:8:2); t:=1;

  for i:=2 to n do

    if g[i,t]=1 then

      begin writeln(text3,i:2,'  1',e[t]:8:2); t:=1 end

    else

      begin  writeln(text3,i:2,'  0',d[t]:8:2); t:=t+1;  end ;

  writeln(f[1,1]:8:3);

  writeln(' 1  0',e[0]:8:2);  t:=1;

  for i:=2 to n do

    if g[i,t]=1 then

      begin writeln(i:2,'  1',e[t]:8:2); t:=1 end

    else

      begin  writeln(i:2,'  0',d[t]:8:2); t:=t+1;  end ;

  close(text3);

end;

begin {main}

  init;

  for i:=0 to n do

    for j:=0 to k do  g[i,j]:=1;

  for i:=0 to k do  f[n+1,i]:=0;

    for i:=1 to n+1 do f[i,k+1]:=-100;

  for j:=n downto 2 do

    begin

      k2:=k; if j<k then k2:=j-1;

      for t:=1 to k2 do

        begin

          p:=e[t]+f[j+1,1];  q:=d[t]+f[j+1,t+1];

          f[j,t]:=p;   g[j,t]:=1;

          if q>p then

            begin g[j,t]:=0;  f[j,t]:=q;  end;

        end;

    end;

  f[1,1]:=d[0]+f[2,1];

  result3;

end.

 

文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |