大榕树——让我们共成长!
大榕树 myDrs.org
您的位置:大榕树 \ 编程       |  Logo语言   |  Pascal语言   |  信息学奥赛   |  高考保送    |  HTML版本
|  信息学奥赛>>解题报告>>NOIP2002提高组-均分纸牌         本站全文搜索: 友情提示:

NOIP2002提高组-均分纸牌
http://www.mydrs.org  2/15/2003  大榕树


NOIP2002 提高组 题一 均分纸牌(存盘名 NOIPG1)
[问题描述]
  有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。
  移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
  现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
  例如 N=4,4 堆纸牌数分别为:
  ① 9 ② 8 ③ 17 ④ 6
  移动3次可达到目的:
  从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。
[输 入]:
  键盘输入文件名。文件格式:
  N(N 堆纸牌,1 <= N <= 100)
  A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)
[输 出]:
  输出至屏幕。格式为:
  所有堆均达到相等时的最少移动次数。‘
[输入输出样例]
a.in:
 4
 9 8 17 6 屏慕显示:
 3
分析:如果你想到把每堆牌的张数减去平均张数,题目就变成移动正数,加到负数中,使大家都变成0,那就意味着成功了一半!拿例题来说,平均张数为10,原张数9,8,17,6,变为-1,-2,7,-4,其中没有为0的数,我们从左边出发:要使第1堆的牌数-1变为0,只须将-1张牌移到它的右边(第2堆)-2中;结果是-1变为0,-2变为-3,各堆牌张数变为0,-3,7,-4;同理:要使第2堆变为0,只需将-3移到它的右边(第3堆)中去,各堆牌张数变为0,0,4,-4;要使第3堆变为0,只需将第3堆中的4移到它的右边(第4堆)中去,结果为0,0,0,0,完成任务。每移动1次牌,步数加1。也许你要问,负数张牌怎么移,不违反题意吗?其实从第i堆移动-m张牌到第i+1堆,等价于从第i+1堆移动m张牌到第i堆,步数是一样的。
如果张数中本来就有为0的,怎么办呢?如0,-1,-5,6,还是从左算起(从右算起也完全一样),第1堆是0,无需移牌,余下与上相同;再比如-1,-2,3,10,-4,-6,从左算起,第1次移动的结果为0,-3,3,10,-4,-6;第2次移动的结果为0,0,0,10,-4,-6,现在第3堆已经变为0了,可节省1步,余下继续。
程序清单
program NOIPG1;
  const maxn=100;
  var i,j,n,step:integer;ave:longint;
      a:array[1..maxn]of integer;
      f:text;filename:string;
  begin
    write('Input filename:');readln(filename);
    assign(f,filename);reset(f);
    readln(f,n);ave:=0;step:=0;
    for i:=1 to n do begin
      read(f,a[i]); inc(ave,a[i]);{读入各堆牌张数,求总张数ave}
    end;
    ave:=ave div n;{求牌的平均张数ave}
    for i:=1 to n do a[i]:=a[i]-ave; {每堆牌的张数减去平均数}
    i:=1;j:=n;
    while (a[i]=0) and (i<n) do inc(i);{过滤左边的0}
    while (a[j]=0) and (j>1) do dec(j);{过滤右边的0}
    while (i<j) do begin
      inc(a[i+1],a[i]);{将第i堆牌移到第i+1堆中去}
      a[i]:=0;{第i堆牌移走后变为0}
      inc(step);{移牌步数计数}
      inc(i);{对下一堆牌进行循环操作}
      while (a[i]=0) and (i<j) do inc(i);{过滤移牌过程中产生的0}
    end;
    writeln(step);
  end.

点评:基本题(较易) 本题有3点比较关键:一是善于将每堆牌数减去平均数,简化了问题;二是要过滤掉0(不是所有的0,如-2,3,0,-1中的0是不能过滤的);三是负数张牌也可以移动,这是辩证法(关键中的关键)。

作 者:湖北伍先军
来 源:原创
共有4611位读者阅读过此文

  • 上篇文章USACO二月初级竞赛中文试题
  • 下篇文章第八届分区联赛复测消息

  • 发送邮件
    保存页面 打印文章 HTML版本 发表评论

    □- 近期热门文章 □- 相关文章
    1. NOIP2006竞赛大纲 [8307]
    2. 七类高中生具有保送资格 [5911]
    3. NOI2006获奖选手名单 [4956]
    4. 关于举办NOIP2006模拟赛的通告 [4107]
    5. Turbo Pascal各语句运行速... [3595]
    6. Turbo王者归来新Delphi免费... [3182]
    7. IOI2006我国4名选手全部获得金... [2946]
    8. 关于APIO2007与IOI2007... [2764]
    9. noip倒计时 by 枯叶蝴蝶 [2684]
    10. 朱泽园:思想上的金牌更重要 [2169]
    关于举办NOIP2006模拟赛的通告
    NOIP2006竞赛大纲
    NOIP2004提高组一等奖名单[推荐]
    NOIP2004提高组普及组分数线
    NOIP2004提高组复赛解题报告
    NOI各省特派员联系表
    NOIP 2004复赛评测工作结束
    NOIP2004竞赛有关问题及解答
    NOIP复赛测评工作紧张有序进行
    NOIP2004提高组复赛试题
     

    关于本站 | 合作伙伴 | 联系方式
    大榕树 版权所有 ©1999-2006 www.myDrs.org 闽ICP备05000721号