zoukankan      html  css  js  c++  java
  • HDU 1029 一道微软面试题

    http://acm.hdu.edu.cn/showproblem.php?pid=1029

    给定一个数组,其中有一个相同的数字是出现了大于等于(n + 1) / 2次的。要求找出来、

    1、明显排序后,中间那个位置的就是ans,复杂度O(nlogn)

    2、

    考虑分治

    假设那个人是ans,那么对于其他人,我都用一个ans去代替它。就是他们两个一起死了,从这个数组中删除。

    那么我最后剩下的那个人当然还是ans,因为它人数都大于一半了。

    同时删除了两个没关的人,那更好了。如果枚举的那两个人都是ans,那么只能记录次数++,

    关键是如何模拟这个过程。能做到O(n)的复杂度。

    考虑用ans和anstime表示答案和答案那个人出现的次数。

    1、如果anstime==0,就是还没确定谁是ans,那么就选当前这个人作为答案。

    2、否则,如果当前枚举的这个人还是ans,那么记录次数+1,否则记录次数-1(大家一起死了)

    最后ans就是答案。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 1e6 + 20;
    LL a[maxn];
    int n;
    void work() {
        for (int i = 1; i <= n; ++i) {
            scanf("%I64d", &a[i]);
        }
        LL ans = 0, anstime = 0;
        for (int i = 1; i <= n; ++i) {
            if (anstime == 0) {
                ans = a[i];
                anstime++; //出现了一次
            } else {
                if (ans == a[i]) { //同一个人的话,出现次数++
                    anstime++;
                } else anstime--; //否则同时删除这两个人
            }
        }
        printf("%d
    ", ans);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        while (scanf("%d", &n) != EOF) work();
        return 0;
    }
    View Code
  • 相关阅读:
    set的使用
    this.$watch(),this.$set(),this.$nextTick()=>{})
    web 错误代码解析
    samba 问题解决
    Linux postfix配置方法
    Linux rhcsa认证考试试题模拟
    Linux 使用nmcli配置网络
    Linux 链路聚合
    Linux ISCSI服务配置
    Linux Apache配置https访问
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5995138.html
Copyright © 2011-2022 走看看