一個不錯的雜湊題

來源:互聯網
上載者:User

連結:  http://www.lightoj.com/volume_showproblem.php?problem=1423

題意簡化後就是:有大概30條跑道,每條跑道上長為50000,(以上都是資料的最大範圍),每條跑道上有一些位置放了欄架,每條跑道的欄架個數不超過5000,

求最長的一段區間,使得這個區間內的每條跑道的欄架個數相等。


咋一看,毫無思路啊,難道說要去枚舉區間長度,5000啊,還要枚舉起點終點,鐵定不行,然而分類裡面是雜湊- -,就往雜湊的方向想想。

每到一個位置pos,每條跑道從0到pos的欄架數組成 了一個序列,a1 a2 a3 .. ak,那麼我們要找最長的以此位置結尾的區間滿足條件,就是找前面的位置中是否存在這樣一個序列

b1 b2 b3 b4 ... bk,使得b[i]+d=a[i];,及每一項的差都相等,那麼中間這段區間就是以當前位置結尾的最長的區間了,看看能更新答案即可。

最後一個問題,怎麼快速的判斷是否存在這樣一個b序列呢,其實我們可以重新定義一下,如果有兩個位置的序列b[i]+d=a[i] (1<=i<=k)  ,即每個數的差相等,我們就定義這是兩個相等的狀態,將整個序列的每個數都減去這個序列的最小值,這兩個序列就變成一樣的序列了,所以,便有了如下方法:將每個位置得到的序列進行雜湊,每到一個位置,只需要判斷這個位置的序列所表示的狀態有沒有被雜湊過即可,沒有被雜湊過的話就記錄當前位置為雜湊映射成的值

用了兩種方法雜湊,一種是map<vector<int>,int>直接用map將整個序列雜湊。。。

另一種是手寫雜湊函數,用鄰接表的方法雜湊

map雜湊:

#include<cstdio>#include<cstring>#include<vector>#include<map>#include<algorithm>using namespace std;int cnt[35][50010];int val[35];int main(){    int t,ca=1,L,K,n;    scanf("%d",&t);    while(t--)    {        map<vector<int>,int> mp;        scanf("%d%d",&L,&K);        memset(cnt,0,sizeof(cnt));        for(int i=1;i<=K;i++)        {            scanf("%d",&n);            for(int j=1,pos;j<=n;j++)            {                scanf("%d",&pos);                cnt[i][pos]++;            }        }        memset(val,0,sizeof(val));        int ans=0;        vector<int>v;        for(int i=0;i<L;i++)        {                v.clear();             int mi=100000;            int mx=-1;            for(int j=1;j<=K;j++)            {                if(cnt[j][i]) val[j]++;                v.push_back(val[j]);                if(mi>val[j]) mi=val[j];                if(mx<val[j]) mx=val[j];            }            if(mx==mi) {ans=i+1;continue;}            for(int j=0;j<v.size();j++)   v[j]-=mi;            if(mp[v]) ans=max(ans,i+1-mp[v]);            else mp[v]=i+1;                   }        printf("Case %d: %d meter(s)\n",ca++,ans);    }    return 0;}

鄰接表:

#include<cstdio>#include<cstring>#include<vector>#include<map>#include<algorithm>using namespace std;int cnt[35][50010];int val[35];const int mod = 9973;const int maxn = 100000;int K;struct NODE{int a[35];int pos;int next;}edge[maxn];int head[mod+1];int tot;int HASH(int num[]){int tmp=0;for(int i=0;i<K;i++){tmp=5000*tmp+num[i];tmp%=mod;}return tmp;}void insert(int num[],int p){int key=HASH(num);for(int i=0;i<K;i++) edge[tot].a[i]=num[i];edge[tot].pos=p;edge[tot].next=head[key];head[key]=tot++;}int find(int num[]){int key=HASH(num);for(int i=head[key],f,j;i!=-1;i=edge[i].next){     for(j=0;j<K;j++) { f=0; if(num[j]!=edge[i].a[j]) break; f=1; } if(f) return edge[i].pos;}return -1;}int main(){    int t,ca=1,L,n;    scanf("%d",&t);    while(t--)    {        memset(head,-1,sizeof(head));tot=0;        scanf("%d%d",&L,&K);        memset(cnt,0,sizeof(cnt));        for(int i=1,j,pos;i<=K;i++)        {            scanf("%d",&n);            for(j=1;j<=n;j++)            {                scanf("%d",&pos);                cnt[i][pos]++;            }        }        memset(val,0,sizeof(val));        int ans=0;        int v[35],cc=0,mi,mx;        for(int i=0,j;i<L;i++)        {            cc=0;             mi=100000;            mx=-1;            for(j=1;j<=K;j++)            {                if(cnt[j][i]) val[j]++;                v[cc++]=val[j];                if(mi>val[j]) mi=val[j];                if(mx<val[j]) mx=val[j];            }            if(mx==mi) {ans=i+1;continue;}            for(j=0;j<cc;j++)   v[j]-=mi;int pos=find(v);            if(pos!=-1) ans=max(ans,i+1-pos);            else insert(v,i+1);        }        printf("Case %d: %d meter(s)\n",ca++,ans);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.