找水王

 

三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个水王,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该水王发帖数目超过了帖子数目的一半。

如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?

 

思路分析:

因为数据量及其庞大,而水王的发帖量超过了一半,所以必有两次水王的id号记录是相邻的,所以两个相邻的元素比较,如果一样的话都留一个,不一样的全部删掉,最后剩下的一定是水王的id。这个思路看上去简单,但是对于一维数组来说删除是一种时间上很不合适的操作(用链表的话我又懒得写那么麻烦。。。),所以应该找一种类似于删除的方法来完成具体实现。说白了这个题这个题得找到一个合适的flag值来做标记,设key这个变量用来记录当前水王id的备选值。接下来就是从头到尾开始循环。第一次循环key值就设置成当前的id即可,flag值置为1。从第二次循环开始就要比较了,如果当前的idkey值相同,则flag自增为1,否则自减1。在后面的循环中,如果出现了flag0的情况,说明当前水王的备选值key不一定正确,此时直接置成当前的id号即可,flag值仍然置为1。重复上述过程,知道循环结束。这样做的道理就是,由于水王发帖量超过了一半,所以用水王的id去一个一个抵消别人的id号,最后还是能够剩下水王的id号,flag的自减变化就模拟了这个抵消的过程。

最后,这个题是编程之美上的一个问题,来源貌似是微软亚洲研究院的一个论坛。

 

 

 1 int main(){
 2     system("title 11找水王");
 3     //这数据我也懒得手动输入了,随便指定一组好了。。。
 4     int a[7] = {1,1,1,2,5,4,1}; 
 5     int round = 0;
 6     int key = 0;
 7     for (int i = 0; i < 7; ++i){
 8         if (round == 0 || i == 0){
 9             key = a[i];
10             round = 1;
11         }
12         else if (key == a[i])round++;
13         else if (key != a[i])round--;
14     }
15     cout <<key<< endl;
16     return 0;
17 }

 

总结:

没啥好总结的,不是很常规的算法题目,没什么普适性的经验可以总结,最多就是培养一种感觉,做这种题心蛮累的。。。

 

 

posted @ 2017-12-23 16:58  messi2017  阅读(136)  评论(0编辑  收藏  举报