HDU 2158 最短区间版大家来找碴(尺取)

题目链接

解题思路

  题面差不多已经用的算法写到脸上了,不过有个问题就是怎么判断枚举的区间符合条件,如果直接暴力的话复杂度就要乘上q,但是如果用一个变量来计数的话,就能让时间复杂度降下来。

代码

const int maxn = 1e5+10;
int n,m,a[maxn],cnt[maxn];
bool ep[maxn];
int main() {
    while(~scanf("%d%d",&n,&m) && (n||m)) {
        for (int i = 1; i<=n; ++i) scanf("%d",&a[i]);
        while(m--) {
            int k, k2 = 0; scanf("%d",&k);
            for (int i = 0,num; i<k; ++i) {
                scanf("%d",&num);
                if (!ep[num]) ++k2;
                ep[num] = true;
            }
            int c = 0, l = 1, r = 1, ans = INF;
            while(true) {
                while(r<=n && c<k2) {
                    if (!cnt[a[r]] && ep[a[r]]) ++c;
                    ++cnt[a[r++]];
                }
                if (c<k2) break;
                ans = min(ans,r-l);
                if (cnt[a[l]]==1 && ep[a[l]]) --c;
                --cnt[a[l++]];
            }
            printf("%d\n",ans);
            for (int i = 0; i<=n; ++i) {
                ep[i] = false; cnt[i] = 0;
            }
        }
    }
    return 0;                                                                 
}
posted @ 2020-07-21 11:04  shuitiangong  阅读(86)  评论(0编辑  收藏  举报