寻找水王·扩展
来源:互联网 发布:淘宝助理怎么下架 编辑:程序博客网 时间:2024/05/16 08:48
题目:随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?
分析:编美里面寻找水王的方法已经说明白了,遍历一遍,每次减少两个元素,将原问题分解成更小规模的问题,这其中的原因是因为减少了问题规模之后原来“水王帖子的数量超过总数的一半”的特性依然存在。扩展的问题思路也是一样,根据题意,水王们的发帖数目一定会超过1/4,因此在后面写代码的时候不考虑找出水王之后验证合不合法。参考原问题的解法,可以知道:如果每次删除四个不同的ID,则在剩下的ID列表中,原先发帖比例大于1/4的ID所占比例仍然大于1/4。不断重复这个过程,最终得到答案。
网上有很多直接在原问题的解法基础上,暴力遍历候选集candidates。在原问题的时候candidates只有一个,使用一个变量来保存就可以,在拓展问题中candidates有三个,因此需要用一个长度为3的数组来保存,另外用于计数candidates出现次数的标志也从原来的一个变量变成一个长度为3的数组。之所以说这种解法暴力,是大家的代码因为有很多if-else,把各种情况考虑周全了。这里转一份网上大神们的参考代码(转载地址,侵删。)
void Find(Type* ID, int N,Type candidate[3]){ Type ID_NULL;//定义一个不存在的ID int nTimes[3], i; nTimes[0]=nTimes[1]=nTimes[2]=0; candidate[0]=candidate[1]=candidate[2]=ID_NULL; for(i = 0; i < N; i++) { if(ID[i]==candidate[0]) { nTimes[0]++; } else if(ID[i]==candidate[1]) { nTimes[1]++; } else if(ID[i]==candidate[2]) { nTimes[2]++; } else if(nTimes[0]==0) { nTimes[0]=1; candidate[0]=ID[i]; } else if(nTimes[1]==0) { nTimes[1]=1; candidate[1]=ID[i]; } else if(nTimes[2]==0) { nTimes[2]=1; candidate[2]=ID[i]; } else { nTimes[0]--; nTimes[1]--; nTimes[2]--; } } return;}
但是,我寻思着,如果不止3个水王呢?如果是4个水王,5个水王,甚至是更多水王?事实上1个水王的时候水贴超过一半,3个水王的时候每人水贴超过1/4,可以推出有n个水王,每人所占水贴超过1/(n+1),因此应该有个通用的思路来找出这些水王。下面是我自己实现,遍历帖子的每一个元素时:1)首先检查candidates中有没有出现过,如果出现过,将对应的计数器加1;2.1)如果全部没有出现过,则找到第一个计数器为0的位置,作为这个candidate的的位置,并把计数器加1;2.2)如果这些candidates的计数器全部不为0,以为着当前元素跟这n个水王候选都不一样,因此删去这(n+1)个人。相应的代码如下,为了便于测试,假设原数组中都是整数,因此可以用负数来初始化候选人数组。
void findKnums(int data[], int size) {if (data == NULL || size <= 0) return;int counts[NUM] = { 0 };int results[NUM] = { -1 };for (int i = 0; i < size; ++i) {bool isInK = false;bool hasZeroCount = false;for (int j = 0; j < NUM; ++j) {if (results[j] == data[i]) {counts[j]++;isInK = true;break;}}if (!isInK) {for (int j = 0; j < NUM; ++j) {if (0 == counts[j]) {results[j] = data[i];counts[j]++;hasZeroCount = true;break;}}if (!hasZeroCount) {for (int j = 0; j < NUM; ++j)counts[j]--;}}}for (int j = 0; j < NUM; ++j)cout << results[j] << " ";cout << endl;}
0 0
- 寻找水王·扩展
- 寻找发帖水王 扩展问题
- 编程之美 寻找发帖水王 扩展问题
- 编程之美2.3寻找发帖水王扩展问题
- 编程之美 2.3 寻找发帖水王扩展问题
- 编程之美 -- 寻找发帖水王,以及扩展题
- 《编程之美》读书笔记: 寻找发帖水王的扩展题
- 《编程之美》读书笔记: 寻找发帖水王的扩展问题 2.3
- 《编程之美》: 寻找发帖水王的扩展问题 2.3
- 编程之美2.3寻找发帖水王和扩展问题
- 《编程之美》寻找发帖水王扩展问题的代码实现
- (1.5.2.3)编程之美 寻找发帖水王 扩展问题
- 寻找发帖"水王" 扩展
- 编程之美 - 寻找灌水王及扩展问题
- 寻找水王
- 寻找发帖水王
- 寻找发帖水王
- 寻找发帖水王
- 在WORD 2007中给公式编号
- bzoj 3505 (排列组合)
- Gears of Programmer--工作
- Linux Mint (应用软件— 虚拟机:Virtualbox)
- 【HTTP】Fiddler(一) - Fiddler简介
- 寻找水王·扩展
- iOS中Apple Pay接入详细教程
- java操作xml文件
- CentOS 7安装mysql
- HDU 1198 Farm Irrigation (并查集)
- 学而不思则罔,学而不思则殆-年终总结
- Java大牛养成记(1)——J2EE13规范
- VS启动调试传递命令行参数
- c++ gui qt4 chap02 find