棋 艺 人 生
 

 日志分类

公  告

日  历
 
登  陆

日志更新

最新评论

留 言 板

搜  索

链  接

Blog信息




 

一道LOGO语言题的不同解法
weiwei 发表于 2010-5-31 14:12:10

2010常熟市信息技术教师解题能力比赛中,第三个编程题大致如下:
  有一队士兵,三人一列,剩二人;五人一列,剩下4人;如果七人一列则正好。问这队士兵最少有几人?
  方法有很多,比赛时,我用了第一种方法。
  一、带步长for循环,用求余函数检测
  比赛时,本想写一行语句,语句如下:
to renshu 
  (for "S 7 1000000[if (and 2=(remainder :S 3) 4=(remainder :S 5)) print :S stop]7) 
 end
  由于第一个编程题我就只写了长长的一行命令,心想这一题还是把[ ]里的另写一个子程序,让程序语句变短些。实际答案就写成了这样:
to renshu
  (for "S 7 1000000[rens]7)  
end
to rens
  make "S3 remainder :S 3
  make "S5 remainder :S 5
  if (and 2=:S3 4=:S5) print :S stop
end
  写好程序反复检查了几遍,没发现有什么问题。晚上在电脑一试,出问题了,电脑找出第一个答案14后,程序没有停止,还在不停地输出,只好按“Ctrl”+“G”中止程序运行。查阅了林正山主编的《LOGO语言竞赛教程》上的相关内容,终于弄明白了程序错在什么地方。原来子程序中的“stop”命令对主程序是不起作用的。要让程序找到第一个答案后停止运行,主程序中必须要加入“stop”命令。修改后的程序如下:
to renshu
  make "K 0
  (for "S 7 1000000[rens if :K=1 stop]7) ;
end
to rens
  make "S3 remainder :S 3
  make "S5 remainder :S 5
  if (and 2=:S3 4=:S5) print :S make "K 1
end
  
  二、for循环,用求余函数检测
  这个程序采用的是for加步长的方法来实现的,判断是否符合条件使用求余函数“remainder”。这里带步长的for循环也可以只用for循环的方法来实现。程序如下:
to renshu
  for "S 1 1000000[if (and 2=(remainder :S 3)  4=(remainder :S 5) 0=(remainder :S 7)) print :S stop] 
 end
  
  三、for循环,用取整函数检测
  判断是否符合条件也可以使用取整函数“int”。程序如下:
to renshu
  for "S 1 1000000[if (and (:S-2)/3=(int (:S-2)/3) (:S-4)/5=(int (:S-4)/5) :S/7=(int :S/7)) print :S stop]
end

  四、尾递归,用求余数函数检测
  程序如下:
to renshu
  make "S 1
  rens :S
end
to rens :S
  if (and 2=(remainder :S 3) 4=(remainder :S 5) 0=(remainder :S 7)) print :S stop
  rens :S+1
end

  五、尾递归,用取整函数检测
  程序如下
to renshu
  make "S 1
  rens :S
end
to rens :S
  if (and (:S-2)/3=(int (:S-2)/3) (:S-4)/5=(int (:S-4)/5) :S/7=(int :S/7)) print :S stop
  rens :S+1
end

  六、用跳转语句来实现
  1、用test检测,程序如下
to renshu
  make "S 0
  label "LOOP
  make "S :S+7
  test 2=remainder :S 3   iff [go "LOOP]
  test 4=remainder :S 5   iff [go "LOOP]
  print :S
end
  或者
to renshu
  make "S 0
  label "LOOP
  make "S :S+1
  test 2=remainder :S 3   iff [go "LOOP]
  test 4=remainder :S 5   iff [go "LOOP]
  test 0=remainder :S 7   iff [go "LOOP]
  print :S
end
  三句test语句可以合并起来,简化后程序如下:
to renshu
  make "S 0
  label "LOOP
  make "S :S+1
  test (and 2=(remainder :S 3) 4=(remainder :S 5) 0=(remainder :S 7)) iff [go "LOOP]
  print :S
end

  2、用if then else语句,程序如下:
to renshu
  make "S 0
  label "LOOP
  make "S :S+1
  if 2=remainder :S 3   then [] else [go "LOOP]
  if 4=remainder :S 5   then [] else [go "LOOP]
  if 0=remainder :S 7   then [] else [go "LOOP]
  print :S
end

  这段程序中三个if语句可以合并成一句,修改后程序如下:
to renshu6
  make "S 0
  label "LOOP
  make "S :S+1
  if (and 2=(remainder :S 3) 4=(remainder :S 5) 0=(remainder :S 7)) then [] else [go "LOOP]
  print :S
end

  ……  

  
  

  

  


阅读全文 | 回复(0) | 引用通告 | 编辑
 


发表评论:

    昵称:
    密码: (游客无须输入密码)
    主页:
    标题:





© COPYRIGHT 2005 ALL RIGHTS RESERVED