一.尺取法
总结:首先这个是离散化里面的题单,但是本题不需要使用到离散化,本题用到了尺取法,也可以理解为双指针,设置一个l = 1 , r = 0, 然后设置一个sum记录里面种类的数量,然后r一直向右扩展,每一次扩展都要维护:<<l的种类数在该区间内>1说明有他没他效果一样,所以直接l++,缩短区间长度,然后如果sum ==所有种类数,那么我们就用ans记录一次答案,最终r<= n,最后得出答案,这里注意的是存所谓的id不能用数组,因为id特别大能到1e9,数组开不了那么大,我们用map去存 。
代码部分:
#include <bits/stdc++.h> using namespace std; const int N = 1e7; #define ll int #define inf 0x3f3f3f3f #define pii pair<ll,ll> ll n,m; struct node { ll x,id; }cow[50010]; map<ll,ll>c,a,idx; bool cmp(node a,node b) { return a.x < b.x ; } map<ll,ll> pp; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; ll total=0; for(ll i = 1 ; i<= n ; i++) { cin>>cow[i].x>>cow[i].id; if(pp[cow[i].id]==0) { total++; pp[cow[i].id]=1; } } sort(cow+1,cow+1+n,cmp); for(int i =1 ; i <= n ; i++) { a[i] = cow[i].x; idx[i] = cow[i].id; } ll sum = 0; ll l=1,r=0; ll ans = 1e9; //c[] 每个代表种类数的数量 while(r < n) { r++; c[idx[r]]++; if(c[idx[r]]==1) sum++; while(c[idx[l]] > 1) { c[idx[l]]--; //if(!c[cow[l].id]) sum--; l++; } if(sum==total) { ans = min(ans,a[r]-a[l]); c[idx[l]]--; if(!c[idx[l]]) { sum--; } l++; } } cout<<ans; return 0; }
总结:本题和上题方法类似,但是我一直超时超了半天发现我有一个没必要的循环很大导致的,还有一开始一直向如何读取输入的数据去转换成上一题,然后发现全当成一个个然后读取就可以了
代码部分:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e7; 4 #define ll int 5 #define inf 0x3f3f3f3f 6 #define pii pair<ll,ll> 7 ll n,k,s,ans=1e9; 8 struct node 9 { 10 int idx; 11 int loc; 12 }gift[1000010]; 13 map<ll,ll>a; 14 map<ll,ll>b; 15 map<ll,ll>c; 16 bool cmp(node x,node y) 17 { 18 return x.loc < y.loc; 19 } 20 int main() 21 { 22 // ios::sync_with_stdio(false); 23 // cin.tie(0); 24 // cout.tie(0); 25 cin>>n>>k; 26 ll m; 27 ll w; 28 for(int i =1 ; i <= k ; i++) 29 { 30 cin>>m; 31 for(int j = 1 ; j <= m ; j++) 32 { 33 gift[++s].idx=i; 34 cin>>gift[s].loc; 35 } 36 } 37 sort(gift+1,gift+1+n,cmp); 38 // for(int i = 1 ; i<= n ; i++) 39 // { 40 // a[i] = gift[i].idx; 41 // b[i] = gift[i].loc; 42 // } 43 ll l = 1 ,r = 0; 44 ll sum = 0; 45 for(ll l = 1 ,r = 1; r<= n;) 46 { 47 c[gift[r].idx]++; 48 if(c[gift[r].idx]==1) 49 sum++; 50 if(sum == k) 51 { 52 ans = min(ans,gift[r].loc - gift[l].loc); 53 while(1) 54 { 55 c[gift[l].idx]--; 56 if(c[gift[l].idx]==0) 57 sum--; 58 l++; 59 if(sum < k) 60 break; 61 else 62 { 63 ans = min(ans,gift[r].loc - gift[l].loc); 64 } 65 } 66 } 67 r++; 68 } 69 cout<<ans; 70 return 0; 71 }