作者 by 超米 / 2024-03-19 / 2 评论 / 60 个足迹
小组问题:“小卡要民主”
佛罗里达州在2000年总统选举中出现了妇孺皆知的“残留纸屑问题”,后来大多数州都不再使用打卡投票的方法,其中,最普遍的替代方案是使用电子投票机。但即便如此却依然存在问题,正如我们在2006年大选中所见,全电子投票无法生成可用于核实的纸质票据,无法重新计票,也难以发现其中的舞弊行为。
为了解决上述问题,可以采用一种新型方法(貌似有点异想天开),依然采用打卡投票的方式,并使用微型机器人卡雷尔检查每张选票残留的纸屑,卡雷尔的任务是检查每张选票,确保票孔没有纸屑残留。
具体点说,假设卡雷尔位于选票最左端,如下图所示
半闭合的矩形是每张选票的打孔区。选票上原本全部都覆盖着方块,如第2第8列所示。在理想的情况下,选民投出的票会打空所有的方块,得 到一个空白的矩形,如第4列所示。可惜会有一些纸屑残留在洞上,如第6列所示,顶部的方块仍留在选票上。第10列的情况更糟,中间打出的方块 覆盖到长方形的底部,在那儿留下了两个方块。
假设州的立法规定,选民的投票意向由矩形中间方块的状态来决定(撞针与卡片接触的位置)。如果中间有方块,卡雷尔则认定选民没有在那一栏投票,继续检查下一张选票,假如中间没有方块,卡雷尔必须检查选票中对的其他两个位置,去除所有的方块,使得选票能被正确计数,上图正确处理后的状态应如下图所示。
你可以参考以下信息:
l 选票只出现在偶数列。选票的实际尺寸可能与例示不同,实际会包含任意数量的矩形选票。卡雷尔始终从最左边矩形的前一格开始,到最右边矩形的后一格结束。
l 如上图所示,每一份选票矩形都是1*3规格。
l 卡雷尔总是从选票矩形的左边开始,面对长方形中心线的投票孔。
l 卡雷尔结束运行时必须在选票最右边,面朝东。
注意:写一个卡雷尔程序清理孔屑,记住,你的程序不应该仅仅适用于图中的例子,而需符合所有情况。
参考代码:
import stanford.karel.*;
public class VoteCountingKarel extends SuperKarel {
public void run() {
move();
while(frontIsClear()){ //没结束前(前面没有墙)进行选票
xuanpiao();
if(frontIsBlocked()){ //结束(前面有墙)
break;
}
move();}
}
private void xuanpiao(){
if(beepersPresent()){ //如果当前路口有方块就移动移动
move();
move();
}
turnLeft();
move();
while(beepersPresent()){ //如果当前路口有方块就捡起
pickBeeper();
}
turnAround(); //向后转
move();
move();
while(beepersPresent()){ //如果前面路口有方块就捡起
pickBeeper();
}
turnAround(); //向后转
move(); //到中间位置
turnRight(); //面朝东
move();
}
}
 评论 2 条