[PAT A、B 2020 Winter] 7-5部分文字列のサブシーケンス(25ポイント)

最短部分文字列を見つけるために、ネットワーク全体には何の問題もありません。< @ _ @ >

最初はわずか18ポイント。私はそれに頼っています、私がクラスAにいたときにそれを少し最適化しました、そしてそれはACであることがわかりました[Hey from it〜]

サブは 、文字列の連続部分です。 サブシーケンスは 、連続的又はないかもしれない文字列の一部であるが、要素の順序が維持されています。たとえば、文字列が与えられた atpaaabpabtt場合、pabt は部分文字列であり、 は部分列 pat です。

文字列Sと部分列Pが与えられると、Pを含むSの最短の部分文字列が見つかるはずです。そのような解が一意でない場合は、左端の部分列を出力します。

部分文字列文字列の連続部分であり、部分文字列文字列内の文字の順序を維持するサブセットあり、連続または不連続にすることができます。たとえば、与えられた文字列 atpaaabpabttpabt部分文字列、および pat はサブ配列です。

文字列Sと部分列Pが与えられた場合、この質問では、Pを含むS内の最短の部分文字列を見つけるように求められます。解が一意でない場合は、開始点から左端の解が出力されます。

入力フォーマット:

各入力ファイルには、2行で構成される1つのテストケースが含まれています。最初の行にはSが含まれ、2番目の行はPです。Sは空ではなく、104以下の英字で構成されています。PはSの空でないサブシーケンスであることが保証されています。

入力により、最初の行に文字列Sが、2番目の行にPが表示されます。Sは空ではなく、104個以下の小文字の英字で構成されます。PはSの空でないサブ列であることが保証されています。

出力フォーマット:

いずれの場合も、Pを含むSの最短の部分文字列を出力します。そのような解が一意でない場合は、左端の部分文字列を出力します。

Pを含むSの最短の部分文字列を1行に出力します。解が一意でない場合は、開始点から左端の解が出力されます。

入力サンプル:

atpaaabpabttpcat
pat

サンプル出力:

pabt

分析:

非常に簡単で、暴力の方法は問題を解決します。まず、文字列内のすべての部分文字列の最初の文字を見つけて、配列で記録します。配列の長さは、文字列内で可能な部分文字列の数です。次に、文字列を1つずつ検索し、最小の長さのサブ列を出力します。

コード:

#include<bits/stdc++.h>   //好东西,实在是令人省心
using namespace std;
int main(){
    string s,p;
    cin>>s>>p;
    vector<int> v;
    for(int i=0;i<s.size();i++)
        if(s[i]==p[0]) v.push_back(i);//找出整个字符串和子串第一个字符相同的所有元素的下标
    int minlen=s.size()+1,mini=0; 
    for(int i=0;i<v.size();i++){//s中可能的子串数
        int cnt=1;//已经找完第一个了 
        for(int j=v[i]+1;j<s.size();j++){
            if(s[j]==p[cnt]) cnt++; //找子串的第1~p.size()-1个字符
            if(cnt==p.size()){//找完了 
            	if(j-v[i]<minlen){
            		minlen=j-v[i];
            		mini=v[i];
				}	
				break;
			}
        } 
    }
    for(int i=mini;i<=mini+minlen;i++)
		cout<<s[i];
    return 0;
}

実際、私が言いたいのは、詳細が最も重要であるということです!それをしたとき、私は目がくらみました。私はいつも私をjと見なし、jを私と見なしました。私は言葉を失いました。

率直に言って、それは論理的な問題です。

でも確かに、私が苦手なのは複雑なロジックの問題です〜

おすすめ

転載: blog.csdn.net/WKX_5/article/details/114480779