牛客练习赛70 重新排列
來源:牛客網:
文章目錄
- 重新排列
- 題解:
- 代碼:
重新排列
時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format:
%lld
題目描述
牛牛有個很喜歡的字符串”puleyaknoi“。
牛牛有T個很長很長的字符串,他很喜歡把字符串中的子串(連續的某段)打亂,并且按照自己的喜好重新排列。
如果牛牛能把一段重新排列出他喜歡的字符串,他就會把這個子串稱作:喜歡的子串。
牛牛是個懶人,他不喜歡對太長的子串進行重排,那樣他會覺著眼鏡很累。
你能幫他求出對于每個字符串,最短的喜歡的子串的長度是多少嗎?
如果沒有,請輸出-1。
輸入描述:
第一行一個表示數據組數
接下來行每行一個字符串(保證字符串只含小寫字母)
輸出描述:
共T行每行一個答案
示例1
輸入
復制
輸出
復制
說明
sxpuleyaaknoip中puleyaaknoi可以重排成puleyaknoia,其中包含有puleyaknoi。
konijiwa不能重新排列出puleyaknoi,所以是-1
備注:
T≤10,字符串長度不超過10^5
題解:
題意很明確,我們來分析一下,我們所要找的滿足條件的區間沒有辦法一下確定,也就是這個區間是需要不斷調整的,因為找到一個區間滿足條件后,有可能不是最簡情況,還能再縮,所以我們可以采用尺取法
我們一開始確定左邊界L=0,然后不斷更新右邊界r,直到r滿足條件,這樣就確定了一個區間,記錄答案,然后左邊界L右移一位,然后右邊界在原先的基礎上找滿足情況的區間,更新區間最小值,這樣一直循環,我們找到了所有滿足情況的區間,并取得最小值,所以找到最優解
記得L右移動一位時,將原本L位置的數據刪除,因為原L的數已經不在現區間里了
詳細看代碼
代碼:
#include<bits/stdc++.h> using namespace std; string w="puleyaknoi"; const int maxn=1e5+9; int a[maxn]={0}; int b[maxn]={0}; const int INF=1e6+9; bool check() {for(int i=0;i<26;i++){if(b[i]&&a[i]<b[i])return 0;}return 1; } int main() {int n;cin>>n;for(int i=0;i<=w.length();i++){b[w[i]-'a']++;}while(n--){string s;cin>>s;int l,r,tot=INF;for(l=0,r=0;l<s.length();l++){while(check()==0&&r<s.length()){a[s[r]-'a']++;r++;}if(check()){tot=min(tot,r-l);}a[s[l]-'a']--;}if(tot==INF)cout<<"-1"<<endl;else cout<<tot<<endl;} }總結
以上是生活随笔為你收集整理的牛客练习赛70 重新排列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吉利汽车:极氪向美国证交会提交上市申请,
- 下一篇: 序列自动机