时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld
题目描述
小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。
小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。
输入描述:
第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。
接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。
输出描述:
应包含一行,为最短彩带长度。
示例1
输入
复制
6 3 1 5 2 1 7 3 1 3 8
输出
复制
3
备注:
题解:
双指针,尺取法
先固定左界为1,然后移动右界,当范围内达到要求的彩珠数量时,固定右届开始移动左界,直到范围内不再包含所有颜色的彩珠,不断更新最小范围
详细可以看代码
不过代码有错误。。。我还没发现。。。。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn=1100045; struct node{ ll col;//颜色 ll xy;//坐标 bool operator <(const node tmp)const{ return this->xy<tmp.xy; } }a[maxn]; long long cnt[maxn]; signed main() { ll n,k; cin>>n>>k; ll ant=0; for(int i=1;i<=k;i++) { ll x; cin>>x; for(int i=1;i<=x;i++) { int y; cin>>y; a[++ant].col=i; a[ant].xy=y; } } sort(a+1,a+1+ant); ll l=1,r=maxn; ll sum=1e9+10; ll tmp; ll res=0;//所选不同颜色彩珠的数量 for(int i=1;i<=ant;i++)//从头开始枚举每一个彩珠 { if(cnt[a[i].col]==0)//说明这个颜色还么选 res++; cnt[a[i].col]++;//加上当前彩珠 while(res==k)//当数量足够时 { tmp=a[i].xy-a[l].xy; sum=min(sum,tmp);//记录最小距离 //-------接下来开始缩小范围 //左边界开始向右靠,缩小边界 cnt[a[l].col]--;//将左边界l的彩珠去掉 if(cnt[a[l].col]==0)res--; l++;//向右靠 } } cout<<sum<<endl; return 0; }