传送门:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27400
Anayse:小顶堆;
1 1 5 - > 1 3 5 -> 3 5 7 -> 5 7 8
pop(1) p(1) p(3) 最优解。
每次剔除堆顶,然后换push与堆顶相同种类的珠子,由于单调,,距离会被缩短,于是找出最优解。详见上式。
push() log(n)
so,复杂度 nlog(n).
Code:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<string> #include<queue> #include<deque> #include<stack> #include<map> #include<set> #define INF 0x7fffffff #define SUP 0x80000000 #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long LL; const int N=100007; int **a; int nu[100]; struct node{ int id,pos; node(int a,int b):id(a),pos(b){}; bool operator <(node a) const { return pos<a.pos; } }; vector<node> aa; int main() { int n,k; while(scanf("%d%d",&n,&k)==2) { mem(nu,0); priority_queue<int,vector<int>,less<int> > que; a=new int *[k+1]; int num; for(int i=1;i<=k;i++) { scanf("%d",&num); a[i]=new int[num+1]; nu[i]=a[i][0]=num; for(int j=1;j<=num;j++) scanf("%d",&a[i][j]); } int cnt=k; for(int i=1;i<=k;i++) //构造初始堆 { aa.push_back(node(i,a[i][1])); nu[i]=2; } int ans=INF; while(cnt<=n) //依次剔除堆顶 { sort(aa.begin(),aa.end()); ans=min(ans,aa[k-1].pos-aa[0].pos); int ii=aa[0].id; if(nu[ii]>a[ii][0]){ break; } aa[0]=node(ii,a[ii][nu[ii]++]); cnt++; } printf("%d\n",ans); } return 0; }
时间: 2024-10-06 20:34:42