任务:
三人行设计了一个灌水论坛。信息学院的学生都喜欢在上面交流灌水,传说在论坛上有一个“水王”,他不但喜欢发帖,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子数目的一半。 如果你有一张当前论坛的帖子(包括回帖)列表,其中帖子的作者的ID也在其中,你能快速的找到这个传说中的水王吗?
1.设计思想:刚看到此题目的时候,以为水王的ID是知道,而且可以用多个变量,进行遍历,再通过一次比较将发帖最多的ID找到就行。但是要求只能有一个变量值,而且要求时间复杂度是O(n),这时候就要考虑换一种思路来解决问题了。假设这里一共有n个帖子,那么水王的帖子数是占一半以上的,就是大于n/2,如果时间复杂度要求是O(n)的话,那也就是只能遍历一次,而且只能有一重循环的结构,所以只能由那个唯一的变量进行ID数量的记录。要找到ID数是总数的一半以上的ID的话,由于每个帖子的位置都是毫无规律的,所以不能进行累加计算,因为ID是一直变化的。然后就想到可以利用加减结合,从第一个ID开始,一次对相邻的两个帖子进行比对,如果说ID相同m就加一,如果不同就减一,到最后m肯定是大于等于0的,只有当m等于0时,将ID赋值为当前ID,就能保证最后的ID是要找的ID。
2.源代码:
#include<iostream> using namespace std; void main() { int i , n, ID[100]; int id = ID[0], num = 0; cout << "请输入帖子的数目:"; cin >> n; cout << "输入每个帖子所对应的ID:"; for (i = 0; i < n; i++) { cin >> ID[i]; } for (int i = 0; i < n; ++i) { if (num == 0) { id = ID[i]; num++; } else if (ID[i] == id) { num++; } else { num--; } } cout << "水王的ID是:" << id << endl; }
3.实验截图:
4.实验总结:(1)在完成每一个程序时都要仔细地研读题目的要求,看它规定的条件,如时间复杂度的要求、变量个数的要求、还有最终结果的形式要求等等诸多因素。因为某个条不一样是设计思路就会有很大的区别,所以在开始设计思路之前一定要把题目完全弄懂,不能因为一些细节而犯错误。
(2)开始的时候,在遍历所有ID的时候,我老是想着对于不相同的ID将计数的变量逐次加一,然后看最后总数大于n/2就行了,可是一想到ID一直在换而且没有规律,如果只有一个变量就无法达到目的了。过了半天才稍微想到可以利用减法计数,相同加一,不同减一,当某个临界的时候改变ID的赋值,思路雏形刚刚有了,然后有同学做了讲解,大致思路是一样的,说明我想的方向是对的。然后再考虑具体的实现过程就可以了。及时转换思路是很重要的。
(3)另外,当一个题目有简单的思路和复杂的思路时, 要多注意比较难一点的设计思路这样会让计算机的运算效率更快。