51Nod 1786 数据流中的算法-众数 题解

来源:互联网 发布:tcp 发送syslog java 编辑:程序博客网 时间:2024/06/17 14:52

题目链接

51Nod-1786 数据流中的算法 - 众数

题意

有一个窗口,窗口中只能存k 个数据,新的数据只能从末尾添加,如果数据量超过k,就删除最先添加进去的数据,在线询问窗口中数据的众数,如果存在多个众数,则输出最小的那个。

题解

用一个map< int, int> num_time 来存当前窗口中的数据和出现次数,用一个结构体Node 来存两个int,一个表示当前窗口中的数据和出现的次数,重载Node 的小于号,比较规则为:以出现次数为主关键字,从小到大,以数据为次关键字,本以为从大到小会最快的,结果发现从小到大的更快,然后放到set< Node> time_num 中。
还有一点要注意的就是,当某个数据出现的次数减少到0 时,要从map 中删掉,这样不会因为后面数据量增大,在map 中寻找的时间变长。
用ios::sync_with_stdio(false); cin cout 时间大概时1300ms,用getchar putchar 只要780ms,贼6

代码

#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>using namespace std;#define LL long longconst int maxn = 1005;struct Node {    int time;    int num;    Node(int t, int n) {        time = t;        num = n;    }};bool operator<(const Node &a, const Node &b) {    if(a.time == b.time) return a.num < b.num;    return a.time < b.time;}struct Que {    int nums[maxn];    int cnt;    int head;    int tail;    Que() {        memset(nums, 0, sizeof(nums));        cnt = head = tail = 0;    }    void push(int x) {        ++cnt;        nums[tail] = x;        tail = (tail + 1) % maxn;    }    int pop() {        int tmp = nums[head];        --cnt;        head = (head + 1) % maxn;        return tmp;    }    int size() {        return cnt;    }};int n, k;Que num;map<int, int> num_time;map<int, int>::iterator it;set<Node> time_num;set<Node>::iterator sit;int command, tmp;char w[10];int read() {    int ans = 0;    char ch;    do {        ch = getchar();    } while(ch < '0' || ch > '9');    do {        ans = ans * 10 + ch - '0';        ch = getchar();    } while(ch >= '0' && ch <= '9');    return ans;}void write(int x) {    if(x == 0) {        putchar('0');    } else {        int cnt = 0;        while(x != 0) {            w[cnt] = x % 10 + '0';            ++cnt;            x /= 10;        }        do {            --cnt;            putchar(w[cnt]);        } while(cnt > 0);    }}int main() {    #ifdef LOCAL    freopen("test.txt", "r", stdin);    #endif // LOCAL    n = read();    k = read();    for(int i = 0; i < n; ++i) {        command = read();        if(command == 1) {            tmp = read();            num.push(tmp);            it = num_time.find(tmp);            if(it == num_time.end()) {                num_time[tmp] = 1;                time_num.insert(Node(1, tmp));            } else {                sit = time_num.find(Node(it->second, tmp));                time_num.erase(sit);                ++it->second;                time_num.insert(Node(it->second, tmp));            }            if(num.size() > k) {                tmp = num.pop();                it = num_time.find(tmp);                time_num.erase(Node(it->second, tmp));                --it->second;                if(it->second == 0) {                    num_time.erase(it);                } else {                    time_num.insert(Node(it->second, tmp));                }            }        } else {            sit = time_num.end();            --sit;            sit = time_num.upper_bound(Node(sit->time, -1));            write(sit->num);            putchar('\n');        }    }    return 0;}
原创粉丝点击