uyhip问题 最苛刻的投票程序

一个国家里有 N 个公民,这些公民从 1 到 N 依次编号。这是一个民主国家,国家做出的每个决定都需要全体公民投票,每个人必须且只能投一票。

不过,随着该国家人口数量的增加,这种投票方式的效率越来越低。于是,这个国家实行了一种新的民主制度。每过四年,这个国家将会举行一次“代表选举大会”,届时,每个公民都必须且只能提名一个他信得过的人,来作为他自己的代表。注意,提名自己作为自己的代表也是允许的。对于每个被提名了的人,有百分之多少的人提名他,他就拥有了相当于多少张选票的权力(向下取整)。在接下来的四年里,国家要做出某项决定时,就只需要这些代表来参加了。

比方说,这个国家有 200 个人,在代表选举大会上,有 98 个人提名 1 号公民当代表,有 101 个人提名 2 号公民当代表,有 1 个人提名 200 号公民当代表。结果就是,只有 1 号公民和 2 号公民成为代表,在接下来的四年里参与投票,其中 1 号公民一票当 49 票,2 号公民一票当 50 票。值得注意的是, 200 号公民虽然有提名,但支持率仅 0.5% ,因此他今后四年没有当代表的权力。

为了支持新的民主政策,你需要设计一套算法,来计算每届代表选举大会结束后,哪些公民成为了代表,他们手中各自有多少票的权力。程序的输入数据来源于一盘磁带。磁带上有 N 个数,分别记录了这 N 个公民各自提名的代表的编号(由于提名是匿名的,磁带上的数据不是顺序的,你无法判断出每个数都是谁的)。程序可以多次读取磁带,但是每次都只能是从头到尾依次读取每一个数。由于这个国家的人数已经增加到了一定规模,因此你的程序必须非常高效。具体地说,你的算法必须要满足以下几点限制:

1. 你的程序读取磁带的次数要尽可能的少;

2. 磁带是只读的;

3. 程序可以在自己的内存里储存变量,不过只能使用 O(1) 个单元的空间(即所耗费的内存空间与 N 无关);

4. 内存里每个单元的空间只能储存 0 到 N 之间的整数(包括 0 和 N );

5. 预处理阶段完成后,程序将进入询问阶段,即针对形如“公民 x 获得了多少票的权力”的问题给出回答。一旦预处理完成进入询问阶段后,程序就不能再接触磁带了。

现在的问题是,在最坏情况下,最少需要读取多少次磁带?给出一个满足要求的算法,并证明读取磁带的次数已经不能再少了。

已知量:候选人最多100个

约束条件:)每个人获得的票数大于等于 N/100才能获选

)投票序列只能顺序遍历,不能随机遍历;可以多次遍历;序列不能被修改

)使用的内存为O(1),每个内存单元只能存0到N的整数

)必须回答任何人获得的投票数,询问的对象可以是任何人

)尽可能少地遍历序列

未知量:设计一个算法,最后能找出所有候选人的选票数

候选人最多有100个,所以最少需要100的内存空间

任何人的数字小于1%,权利值即为0,不需要记录他获得的选票数。因此问题可以理解为 找出序列当中所有出现了大于1%数字

尝试减少约束条件,如果可以使用更多的内存空间。我们可以使用O(n)的空间统计每个数出现了多少次。

然后收集计数>=1%的数字。如此一来,“)每个人获得的票数大于等于 N/100才能获选”这个条件没有用上(你是否用到了所有条件)

所以这个问题的关键是:如何利用一些数字的占比>=%1这个条件

为了便于思考,我们把问题特殊化,寻找序列中1/2以上的数字。这个问题似乎简单一些。(特殊化)

由于看过《编程之美》,能够想起”寻找发帖水王“这个问题,正是寻找出现一半以上的数字。(你是否能够想到一道相似的问题?)

寻找ID序列当中出现一半以上的ID

这个问题的解答非常巧妙。只需要遍历一遍序列。最关键的是如何利用有一个数字出现了一半以上。

内存字典,记录两个数字和这两个数字的计数。遍历过程中,如果凑齐了两个数字,就把它们计数减1。如果计数为0,就把这个数字丢掉。这个操作称为清理

遍历序列时,如果这个数字记录在字典中,把内存的计数加1。否则添加到字典中,计数设为1。然后,执行清理操作。

每一次都会清理两个不同的数字,目标数字还是保持一半以上,问题的规模减小了。遍历完所有序列以后,最后只会剩下一个数字。

扩展问题:如果有3个数字都超过1/4,剩下的数字不到1/4,这个问题如何解答?

还是使用上面的方法,只是字典中需要记录4个数。

按照这种方式如果有99个数字超过了1%,剩下的数不到1%,是不是就和原先的问题等价?

并非如此,我们的问题当中超过1%的数字可以有0到100个,未必是99个。

尝试使用上面的方法,运用到我们问题的情景当中。最后的情况是如何的?(是否能运用它的方法?)

似乎,出现次数大于等于1%的数都会出现在我们的字典当中,但是少于1%的数也会出现在我们的字典当中。

当然需要注意一些细节:如果序列当中有100个数,每个占比1%,如果在遍历完最后一个数以后,这时候每个数的计数都是1,再次执行清除,会导致所有的数都会被丢弃。

概括地说,最后一次的清理,会导致占比小于等于1%的数字被清理掉。占比1%的数是需要记录下来的。遍历最后一个数后不能做清理。

1)首先,第一次遍历完以后,字典中有100个数,其中保留了占比大于等于1%的数字,还有一些占比小于1%的数字。

2)然后,我们只要再遍历序列一遍,统计这100个数出现了多少遍。

3)最后,再收集第二次遍历中出现次数大于等于1%的数,以及它们的的计数。

uyhip问题 最苛刻的投票程序

时间: 2024-07-31 13:50:03

uyhip问题 最苛刻的投票程序的相关文章

Bluemix云端数据库服务ClearDB MySQL使用示例———Python开发投票程序

越来越多的服务走向云端,看不见摸不着,让没接触过的我感觉有些茫然,IBM的云平台Blumemix上提供了很多服务,我这里就把学习使用ClearDBMySQL Database服务的过程给大家分享一下.这是一个PHP的投票小程序,针对主题"你曾后悔进入 IT 行业吗?"展开投票功能,基于简单的Cookie操作判断用户有没有投过票,如果没有投过票,就显示投票选项和按钮,不显示投票结果:如果已经投票了,就直接显示投票结果,而不能再次投票. 构建一个类似的应用程序的前提条件 一个 Bluemi

Cookie投票程序

在前台页面先加入RadioButtonList控件 if (!IsPostBack) { Per(); } } protected void btn_toupiao_Click(object sender, EventArgs e) { string P_str_IP = Request.UserHostAddress.ToString();//获取客户端IP地址 HttpCookie oldCookie = Request.Cookies["userIP"]; if (oldCook

利用map的特性做一个简易的投票程序

pair 1. 概念:pair是 一种模版类型,每个pair 可以存储两个值,这两种值的类型无限制.也可以将自己写的struct类型的的对象放进去. 2. 用法: pair<int ,int >p (1,2); pair<int ,int > p1= make_pair(1,2); 3. 编写程序读入一系列string和int型数据,将每一组存储在一个pair对象中,然后将这些pair对象存储在vector容器并显示 #include<iostream> #includ

Bluemix云端数据库服务使用示例———PHP投票程序

越来越多的服务走向云端,看不见摸不着,让没接触过的我感觉有些茫然,IBM的云平台Blumemix上提供了很多服务,我这里就把学习使用ClearDB MySQL Database服务的过程给大家分享一下.这是一个PHP的投票小程序,针对主题"你曾后悔进入 IT 行业吗?"展开投票功能,基于简单的Cookie操作判断用户有没有投过票,如果没有投过票,就显示投票选项和按钮,不显示投票结果:如果已经投票了,就直接显示投票结果,而不能再次投票. 构建一个类似的应用程序的前提条件 一个 Bluem

织梦自己写的投票程序

<?phpob_start();session_start();require_once("config.php");?> <!---表单部分点击投票<form name="frm" action="{dede:global.cfg_cmsurl/}/toupiao/index.php" method="post"><input type="hidden" name=&q

翁恺老师零基础学JAVA语言第五周数组--投票程序例题-个人理解

// 输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1表示结束 // 需要一个int[10]的数组来录入每次输入的数字;需要一个n表示每次输入的数字 // num[] = {0,1,2,3,4,5,6,7,8,9},刚好对应0-9这10个数字 Scanner in = new Scanner(System.in); int[] num = new int[10]; int n = in.nextInt(); if(n >= 0 && n <= 9) {

10个程序员必须学会接受的残酷真相

大多数时候,写代码都是挺有意义的一件事,不光能增加经验值,解决难题的时候还特别爽.耐心.毅力.执着,再加上正确的工具——只要有它们的亲密协作,优雅.漂亮的代码就是手到擒来的事儿. 但是,紧接着拙劣的资源部署.新增的特性请求.糟糕的文档更新汹涌而来,打破了我们的美梦. 但是这并不是说我们的努力就没有价值.只是我们需要面对现实罢了.下面就是编程开发人员必须接受的10个残酷真相. 残酷的开发真相No. 1: 编程就是if-then-else语句的运用 编程语言设计者讨论.抽象化思考等等作为,其实都只是

我看小程序系列文章:1 不一样的角度 解读微信小程序

大家好,我是Beta007. 最近一直在研究小程序,会在这里整理出一系列的文章,和大家交流. 第一篇文章首发在了知乎专栏:小楼昨夜又秋风:https://zhuanlan.zhihu.com/p/22891188 知乎ID:七月在夏天  (头像是只喵~) 不一样的角度 解读微信小程序 七月在夏天· 2 天前 前段时间看完了雨果奖中短篇获奖小说<北京折叠>.很有意思的是,张小龙最近也要把应用折叠到微信里,这些应用被他称为:小程序. 含着金钥匙的小程序,还未展现全貌,就已经成了开发界的头条大事儿.

Android安全问题 程序锁

导读:本文介绍如何实现对应用加锁的功能,无须root权限 某些人有时候会有这样一种需求,小A下载了个软件,只是软件中的美女过于诱惑与暴露,所以他不想让别人知道这是个什么软件,起码不想让别人打开浏 览.而这款软件又没有锁,任何人都可以打开,肿么办呢?如果打开它的时候需要输入密码,那该多好阿!于是,程序锁这种应用就产生了 程序锁不是最近才有的,很久之前android就有这种apk了 这一期我们来苛刻如何实现程序加锁功能 首先,我们先明确一下我们要做的程序具有什么功能 1可以选择需要加锁的程序 2可以