P2564 [SCOI2009]生日礼物

two-pointers problem

There is a similar problem called "guanghuazhan". You can find it in my blog.

Obviously we can use two pointers. But the index is too large!

An easy solution: Li San Hua!!!

Keep all the information for each jewel and sort by the position. Now you can run our dear two-pointer!

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 1000005;
const int INF = 0x3f3f3f3f;
struct Nodes
{
    int pos, col;
} s[maxn];
int tot;
int cnt[65];
int n, k;
bool cmp(Nodes a, Nodes b)
{
    return a.pos < b.pos;
}
int two_pointers()
{
    int l = 1, r = 0, res = 0, ans = INF;// l and r refer to index in array s
    memset(cnt, 0, sizeof cnt);
    while(l <= n)
    {
        while(r < n && res < k)
        {
            r++;
            if(++cnt[s[r].col] == 1) res++;
        }
        if(res == k) ans = std::min(ans, s[r].pos - s[l].pos);
        if(--cnt[s[l].col] == 0) res--;
        l++;
    }
    return ans;
}
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
    return s * ans;
}
int main()
{
    n = read(), k = read();
    for(int i = 1; i <= k; i++)
    {
        int m = read();
        while(m--)
        {
            s[++tot].pos = read();
            s[tot].col = i;
        }
    }
    std::sort(s + 1, s + tot + 1, cmp);
    //for(int i = 1; i <= tot; i++) printf("%d %d\n", s[i].pos, s[i].col);
    printf("%d\n", two_pointers());
    return 0;
}
posted @ 2018-10-28 10:05  Garen-Wang  阅读(149)  评论(0编辑  收藏  举报