[SCOI2009]生日礼物
[SCOI2009]生日礼物
https://ac.nowcoder.com/acm/problem/20565
题意:
小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。
题解:
双指针。
利用STL里面的pair容器,默认排序的性质,就可以不需要自己写一个自定义函数了。
因为宝石的种类很少,当我们每取一段范围时,我们暴力判断以下这个区间是否满足。
时间复杂度 O(nlogn+n*60) ?
双指针判断条件
如果这段区间的宝石满足 题目要求
那么我们r++,同时加上此位置的宝石数目。
如果满足了我们就l++,同时减去那个位置的宝石数目。
这里的区间5-8的区间长度是3,不是4 ,注意一下即可.
代码:
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<iostream> #include<cstdio> #include <string.h> #include<queue> #include<set> #include<map> #include<stack> #include<vector> #include<cmath> #include <math.h> #include<algorithm> //#define int long long using namespace std; const int maxn = 100; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1e9+7; vector <pair<int,int> > v; int visited[100]; int n,k; bool check(){ for(int i=1;i<=k;i++){ if(visited[i]==0) return false; } return true; } signed main(){ cin>>n>>k; for(int i=1;i<=k;i++){ int m; cin>>m; for(int j=0;j<m;j++){ int x; scanf("%d",&x); v.push_back(make_pair(x,i)); } } sort(v.begin(),v.end()); int l=0,r=0; int ans=MaxN; //for(auto it:v) cout<<it.first<<" "<<it.second<<endl; visited[v[0].second]++; while(r<n){ //cout<<l<<" "<<r<<endl; if(check()){ ans=min(ans,v[r].first-v[l].first); visited[v[l].second]--; l++; } else{ r++; visited[v[r].second]++; } } cout<<ans<<endl; return 0; }
题解 文章被收录于专栏
主要写一些题目的题解