1. 程式人生 > >水題 1293: [SCOI2009]生日禮物

水題 1293: [SCOI2009]生日禮物

本來想找點單調佇列做做。。。。然而這個題並不用。。只要雙指標就行了。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int maxn = 1000000;

#define mp(x, y) make_pair(x, y)

pair<LL, int> p[maxn];
int cnt[105];
int n, kk;

bool check(int pos)
{
	cnt[p[pos].second]--;
	int ok = 1;
	for(int i = 1; i <= kk && ok; i++) if(!cnt[i]) ok = 0;
	if(ok) return true;
	cnt[p[pos].second]++;
	return false;
}

void work()
{
	memset(cnt, 0, sizeof cnt);
	
	LL x;
	int m, a = 0, pos, pos2;
	for(int i = 1; i <= kk; i++) {
		scanf("%d", &m);
		for(int j = 1; j <= m; j++) {
			scanf("%lld", &x);
			p[a++] = mp(x, i);
		}
	}

	sort(p, p+a);
	
	for(pos = 0; pos < a; pos++) {
		cnt[p[pos].second]++;
		int ok = 1;
		for(int j = 1; j <= kk && ok; j++) if(!cnt[j]) ok = 0;
		if(ok) break;
	}
	
	LL ans = p[pos].first - p[0].first;
	for(pos++, pos2 = 0; pos < a; pos++) {
		cnt[p[pos].second]++;
		while(check(pos2)) pos2++;
		ans = min(ans, p[pos].first - p[pos2].first);
	}
	
	printf("%lld\n", ans);
}

int main()
{
	while(scanf("%d%d", &n, &kk) != EOF) {
		work();
	}	
	
	return 0;
}