Early Orders
题意
n个数从中找出一个包含1-k的字典序最小子串,注意子串可以断开,但是相对顺序不能变
题解
求得是字典序最小的子串,用一个单调栈维护,从栈底到栈顶依次表示子串的从前到后,为什么用栈呢?考虑子串的先后性,必须先把后面的更新了才能更新前面的,如何维护栈呢?对于栈顶元素,从左往右遍历的过程中如果这个数字比栈顶数字小,而且右面还有栈顶数字,那就可以出栈,还有就是当栈内有一个元素了,这时就不能再往里面塞这个元素,搞一个标记数组标记栈中是否有这个元素
CODE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <bits/stdc++.h> #define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) using namespace std; const int MAXN=1e6; stack<int> st; bool vis[MAXN]; int ans[MAXN],a[MAXN],pos[MAXN]; int main() { ios; int n,m; cin>>n>>m; for(int i=1;i<=n;i++){ cin>>a[i]; pos[a[i]]=i; } for(int i=1;i<=n;i++){ if(vis[a[i]]) continue; while(!st.empty() && a[i]<st.top() && pos[st.top()]>i){ vis[st.top()]=0; st.pop(); } st.push(a[i]); vis[a[i]]=1; } int tail=0; while(!st.empty()){ ans[++tail]=st.top(); st.pop(); } for(int i=tail;i>=1;i--) cout<<ans[i]<<' '; return 0; }
|
这道题和之前我们学校的招新赛一道题很类似,河南理工大学19级新生程序设计大赛:C. 星星选字符串
题意:在S串中找出包含T串所有字符的长度最短的连续子串
题解:用尺取做,当前区间满足条件了就缩小区间,不满足就扩大,这里需要注意的是最好用左闭右开的方式,因为如果左闭右闭的话,尺取的开始不好初始化左右指针的值,假如S=BA,T=B,那第一次就找到了,这时候l=-1,r=0,而你更新长度时条件是len>r-l+1,这时就多计算了一个+1,因为这时候l所在的位置是空的,它没有占有一个字符所以这个+1就是多余的,所以可以刚开始初始化为l=0,r=0,只要在循环外面判断一次第一个字符就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <bits/stdc++.h> #define debug freopen("in.txt","r",stdin); freopen("out.txt","w",stdout) #define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) using namespace std; typedef long long ll; typedef unsigned long long ull; const int MAXN=1e6+100; const int MOD=1e9+7; const int INF=0x3f3f3f3f; const int SUB=-0x3f3f3f3f; const int eps=1e-4; const double E=exp(1); const double pi=acos(-1); string s,t; map<char,int> mp,mp2; int main(){ ios; cin>>s>>t; int len=t.size(),k=0; for(int i=0;i<len;i++){ if(!mp[t[i]]){ mp[t[i]]=1; k++; } } int l=0,r=0,ans=INF,len2=s.size(),lp,rp,cnt=0; if(r<len2 && mp[s[r]]){ mp2[s[r]]++; cnt++; } while(r<len2){ if(cnt==k){ if(ans>r-l+1){ ans=r-l+1; lp=l; rp=r; } if(mp2[s[l]]){ mp2[s[l]]--; if(mp2[s[l]]==0) cnt--; } l++; } else{ r++; if(mp[s[r]]){ mp2[s[r]]++; if(mp2[s[r]]==1) cnt++; } } } if(ans!=INF)cout<<ans<<'\n'; else cout<<-1<<'\n'; return 0; }
#include <bits/stdc++.h> #define debug freopen("in.txt","r",stdin); freopen("out.txt","w",stdout) #define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) using namespace std; typedef long long ll; typedef unsigned long long ull; const int MAXN=1e6+100; const int MOD=1e9+7; const int INF=0x3f3f3f3f; const int SUB=-0x3f3f3f3f; const int eps=1e-4; const double E=exp(1); const double pi=acos(-1); string s,t; map<char,int> mp,mp2; int main(){ ios; cin>>s>>t; int len=t.size(),k=0; for(int i=0;i<len;i++){ if(!mp[t[i]]){ mp[t[i]]=1; k++; } } int l=0,r=0,ans=INF,len2=s.size(),lp,rp,cnt=0; while(r<=len2){ if(cnt==k){ if(ans>r-l){ ans=r-l; lp=l; rp=r; } if(mp2[s[l]]){ mp2[s[l]]--; if(mp2[s[l]]==0) cnt--; } l++; } else{ if(mp[s[r]]){ mp2[s[r]]++; if(mp2[s[r]]==1)cnt++; } r++; }
} if(ans!=INF) cout<<ans<<'\n'; else cout<<-1<<'\n';
return 0; }
|