[洛谷P2397]yyy loves Maths VI (mode)
题目大意:有$n(n\leqslant2\times10^6)$个数,找众数,保证众数出现次数超过一半(内存必须是$O(1)$)
题解:摩尔投票法。因为众数出现次数超过一半,所以这个众数必然会只有$1$个。
每一轮投票时,从数组中找出一对不同的元素,将它们删除。如果数组为空,则此时没有任何元素出现的次数超过该数组长度的一半。若不是空的,则此时数组内剩下的数出现此时超过一半。
所以可以用一个计数器存一下现在出现次数最多的数比现有的数的一半多多少,当计数器等于$0$时,更新答案,最后剩下的一定是出现次数大于一半的数
卡点:无
C++ Code:
#include <cstdio> #include <cctype> namespace R { int x; char ch; inline int read() { ch = getchar(); while (isspace(ch)) ch = getchar(); for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15); return x; } } using R::read; int n, last, cnt; int main() { n = read(); for (register int i = 1, x; i <= n; i++) { x = read(); if (!cnt) last = x; if (x != last) cnt--; else cnt++; } printf("%d\n", last); return 0; }