zoukankan      html  css  js  c++  java
  • 贪心+枚举/哈希表 HDOJ Trouble

    题目传送门

    题意:5个集合,每个集合最多200个数字,问是否每个集合挑一个数加起来和为0。

    分析:显然n^5的程序果断超时,甚至n^3logn的二分也过不了。想n^3的方法,既然判断有没有,那么可以将两个两个的集合合并成两个大集合,再枚举最后一个集合,两个大集合排完序之后一个指针从开头最小开始,另一个从最大的开始,>0,大指针往左移,<0,小指针往右移,那么可以在线性时间求解,这贪心方法很巧妙!

    另一种做法算是暴力+优化了,哈希表储存一个两个集合合并后大集合的数字,n^3暴力询问是否哈希表内存在它的相反数,哈希表用到链式前向星,总算有点理解了,贴张图:

    收获:1. ”微调“贪心方法 2. 哈希表 + 链式前向星

    代码1(贪心):

    /************************************************
     * Author        :Running_Time
     * Created Time  :2015-8-26 9:07:01
     * File Name     :HDOJ_4334.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 2e2 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    ll a[5][N];
    ll sum[2][N*N];
    
    int main(void)    {
        int T; scanf ("%d", &T);
        while (T--) {
            int n;  scanf ("%d", &n);
            for (int i=0; i<5; ++i) {
                for (int j=0; j<n; ++j) {
                    scanf ("%I64d", &a[i][j]);
                }
            }
            int tot = 0;
            for (int i=0; i<n; ++i) {
                for (int j=0; j<n; ++j) {
                    sum[0][tot] = a[0][i] + a[1][j];
                    sum[1][tot++] = a[2][i] + a[3][j];
                }
            }
            sort (sum[0], sum[0]+tot);
            sort (sum[1], sum[1]+tot);
            int cnt1 = 1, cnt2 = 1;
            for (int i=1; i<tot; ++i) {                                     //其实离散化没什么优化
                if (sum[0][i] != sum[0][i-1])   sum[0][cnt1++] = sum[0][i];
                if (sum[1][i] != sum[1][i-1])   sum[1][cnt2++] = sum[1][i];
            }
    
            bool flag = false;
            for (int i=0; i<n && !flag; ++i) {
                for (int j=0,k=cnt2-1; j<cnt1 && k>=0; )  {
                    ll tmp = a[4][i] + sum[0][j] + sum[1][k];
                    if (tmp == 0)   {
                        flag = true;    break;
                    }
                    else if (tmp < 0)   j++;
                    else    k--;
                }
            }
    
            printf ("%s
    ", flag ? "Yes" : "No");
        }
    
        return 0;
    }
    

    代码2(哈希表):

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-26 18:21:55
    * File Name     :D_2.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 2e2 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e6 + 7;
    struct Hash_Table   {
        struct Edge {
            ll x;
            int nex;
        }edge[MOD];
        int head[MOD], E;
        void init(void) {
            memset (head, -1, sizeof (head));
            E = 0;
        }
        void insert(ll x)   {
            int u = (x % MOD + MOD) % MOD;
            for (int i=head[u]; ~i; i=edge[i].nex)  {
                if (edge[i].x == x) return ;
            }
            edge[E].x = x;  edge[E].nex = head[u];
            head[u] = E++;
        }
        bool find(ll x) {
            int u = (x % MOD + MOD) % MOD;
            for (int i=head[u]; ~i; i=edge[i].nex)  {
                if (edge[i].x == x) return true;
            }
            return false;
        }
    }ha;
    ll a[5][N];
    
    int main(void)    {
        int T;  scanf ("%d", &T);
        while (T--) {
            int n;  scanf ("%d", &n);
            for (int i=0; i<5; ++i) {
                for (int j=0; j<n; ++j) scanf ("%I64d", &a[i][j]);
            }
            ha.init ();
            for (int i=0; i<n; ++i) {
                for (int j=0; j<n; ++j) {
                    ha.insert (a[0][i] + a[1][j]);
                }
            }
            bool flag = false;
            for (int i=0; i<n && !flag; ++i) {
                for (int j=0; j<n && !flag; ++j) {
                    for (int k=0; k<n; ++k) {
                        if (ha.find (-(a[2][i] + a[3][j] + a[4][k])))   {
                            flag = true;    break;
                        }
                    }
                }
            }
            puts (flag ? "Yes" : "No");
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    Easily Get NonARC Enabled Open Source Libraries Working In ARC Enabled Projects
    PhoneGap From Scratch (2) : Device APIs
    PhoneGap From Scratch (3) : App Template
    iOS 5 Storyboard and UITableViews Tutorial
    PhoneGap From Scratch (4) : Twitter & Maps
    [原创] Learning in Python:Chapter 5 Numeric Types
    [原创] 程序员面试宝典:第十三章 数据结构基础
    [原创] Learning in Python:Chapter 4 Introducing Python Object Types
    [原创] 程序员面试宝典:第十章 面向对象
    [原创] 程序员面试宝典:第七章 指针与引用
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4761394.html
Copyright © 2011-2022 走看看