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;
}