1 条题解

  • 0
    @ 2026-8-4 10:09:20

    直接考虑如何让两个字符串相同,我们注意到如果你想要指定修改某个字符,你就需要删除掉那个字符后的所有字符,然后再重新添加。

    既然如此,重复地删除同一个字符是没有意义的,所以我们不如倾定一个位置(显然需要满足在这之前的所有字符都是相同的),再把之后的全部字符都删掉,然后再加回来。代价是很好算的,假设我们要让 S2S_2 变成 S1S_1,对于每一个长度为 ii 的前缀,代价就是 S1+S22×i|S_1|+|S_2|-2\times i

    显然我们可以使用 trie 快速处理前缀,那么只要在插入的时候更新包含这个前缀的最短字符串,然后就可以了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int id;
    int trie[200005][30];
    int dep[2000005];
    int val[200005];
    void ins(string s){
    	int ji=0;
    	for(int i=0;i<s.size();i++){
    		if(!trie[ji][s[i]-'a']){
    			trie[ji][s[i]-'a']=++id;
    		}
    		dep[trie[ji][s[i]-'a']]=dep[ji]+1;
    		ji=trie[ji][s[i]-'a'];
    		val[ji]=min(val[ji],int(s.size()));
    	}
    }
    int run(string s){
    	int ji=0,i=0;
    	s=s+char('z'+1);
    	int ans=1e9+7;
    	for(;i<s.size();i++){
    		ans=min(ans,val[ji]+int(s.size())-2*i-1);
    		if(!trie[ji][s[i]-'a']){
    			return ans;
    		}
    		ji=trie[ji][s[i]-'a'];
    	}
    }
    int main(){
    	memset(val,0x3f,sizeof(val));
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		string s;
    		cin>>s;
    		cout<<min(run(s),int(s.size()))<<"\n";
    		ins(s);
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    7914
    时间
    2000ms
    内存
    1024MiB
    难度
    7
    标签
    递交数
    16
    已通过
    9
    上传者