Description
小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。
Input
第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。
Output
应包含一行,为最短彩带长度。
思路:使用尺取法,按对读入,按x坐标排序后尺取即可
代码:
#include<cstdio> #include<algorithm>
const int INF = 0x7fffffff; struct Node { int x, t; bool operator< (const Node &a) const { return x < a.x; } } Nodes[1000010]; int n, k, vis[64]; int main() { scanf("%d%d", &n, &k); int Nsize = 0; for (int i = 1; i <= k; ++i) { int m; scanf("%d", &m); while (m--) { int tmp; scanf("%d", &tmp); Nodes[Nsize].x = tmp, Nodes[Nsize++].t = i; } } sort(Nodes, Nodes + Nsize); int l = 0, r = 0, t = 0, ans = INF; while(1) { while(t < k && r <= n) { if(!vis[Nodes[r++].t]++) t++; } if(r > n) break; while(1) { if(!--vis[Nodes[l++].t]) { ans = min(ans, Nodes[r-1].x - Nodes[l-1].x); --t; break; } } } printf("%d ", ans); return 0; }