景德镇市网站建设_网站建设公司_需求分析_seo优化
2025/12/25 1:07:53 网站建设 项目流程

题目描述

给定两个小写字母字符串aaabbb,要求构造一个最短的小写字母字符串xxx,使得axaxaxbxbxbx这两个拼接字符串中恰好有一个是回文串(即反转后与自身相等),另一个不是。

输入格式

标准输入包含多组数据,每组数据包含两行,每行一个字符串。字符串由小写字母组成,长度在000100010001000之间。

输出格式

对于每组数据,输出一行答案字符串xxx。如果存在多个满足条件的xxx,选择长度最短且字典序最小的那个。如果不存在这样的xxx,输出No solution.

样例输入

abab ababab abc def

样例输出

baba ba

题目分析

本题要求构造一个字符串xxx,使得a+xa+xa+xb+xb+xb+x中恰好一个是回文串。我们需要找到最短且字典序最小的解。

问题特点

  1. 回文性质:如果s+xs+xs+x是回文串,那么它的反转等于自身:reverse(s+x)=s+xreverse(s+x) = s+xreverse(s+x)=s+x
  2. 结构约束:设rev(s)rev(s)rev(s)表示sss的反转。若s+xs+xs+x是回文,则有:
    s+x=reverse(s+x)=reverse(x)+rev(s) s + x = reverse(s+x) = reverse(x) + rev(s)s+x=reverse(s+x)=reverse(x)+rev(s)
    这意味着xxx必须与rev(s)rev(s)rev(s)的某个后缀匹配。

关键观察

经过推导,我们可以得到一个重要结论:
如果s+xs+xs+x是回文串,那么xxx一定是rev(s)rev(s)rev(s)的某个后缀,且该后缀对应的前缀是回文串

证明:
n=∣s∣n = |s|n=sm=∣x∣m = |x|m=x
由于s+xs+xs+x是回文,其长度为n+mn+mn+m。考虑字符串的后mmm个字符,即xxx
因为回文对称性,xxx必须等于rev(s)rev(s)rev(s)的前mmm个字符。
同时,为了保证整个字符串是回文,rev(s)rev(s)rev(s)的前mmm个字符(即xxx的反转)必须与sss的后mmm个字符匹配。
更形式化地,可以证明:xxxrev(s)rev(s)rev(s)的后缀,且rev(s)rev(s)rev(s)去掉这个后缀后剩下的前缀是回文串。

解题思路

基于上述观察,我们可以设计如下算法:

1. 特判

如果a=ba = ba=b,那么对于任意xxxa+xa+xa+xb+xb+xb+x总是同时为回文或同时不为回文,因此不存在解,直接输出No solution.

2. 构造候选解

对于每个字符串sssaaabbb),我们构造所有可能的xxx,使得s+xs+xs+x是回文串。方法如下:

  1. 计算rev=reverse(s)rev = reverse(s)rev=reverse(s)
  2. 枚举分割点iii(从−1-11n−1n-1n1,其中n=∣rev∣n = |rev|n=rev):
    • prefix=rev[0…i]prefix = rev[0 \dots i]prefix=rev[0i](当i=−1i=-1i=1时为空串)
    • 如果prefixprefixprefix是回文串,则x=rev[i+1…n−1]x = rev[i+1 \dots n-1]x=rev[i+1n1]是一个候选解
  3. 额外考虑一种情况:在revrevrev前面添加一个字符cccccc'a''z'),得到c+revc + revc+rev作为候选解。这对应了xxxrevrevrev长一个字符的情况。

3. 合并与筛选

  1. 分别计算aaabbb的候选解集合AAABBB
  2. 合并两个集合,去重并按照长度优先、字典序次优先排序。
  3. 遍历排序后的候选解,检查每个xxx是否满足条件(a+xa+xa+xb+xb+xb+x恰好一个是回文)。
  4. 输出第一个满足条件的xxx

4. 复杂度分析

  • 回文判断:O(n)O(n)O(n),其中nnn是字符串长度。
  • 构造候选解:枚举O(n)O(n)O(n)个分割点,每个点做一次O(n)O(n)O(n)的回文检查,共O(n2)O(n^2)O(n2)
  • 候选解数量:O(n)O(n)O(n)个。
  • 排序:O(nlog⁡n)O(n \log n)O(nlogn)
  • 总复杂度:O(n2)O(n^2)O(n2),对于n≤1000n \leq 1000n1000完全可行。

5. 正确性证明

算法的正确性基于上述数学推导:我们枚举了所有可能使s+xs+xs+x成为回文的xxx。因此,如果存在解,它一定在候选解集合中。我们按长度和字典序排序后遍历,找到的第一个满足“恰好一个回文”条件的解就是题目要求的最优解。

代码实现

// Suffidromes// UVa ID: 10262// Verdict: Accepted// Submission Date: 2025-12-24// UVa Run Time: 0.010s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;boolcmp(string a,string b){if(a.size()!=b.size())returna.size()<b.size();returna<b;}// 判断回文boolisPalindrome(conststring&s){intleft=0,right=s.size()-1;while(left<right)if(s[left++]!=s[right--])returnfalse;returntrue;}// 获取所有可能的 x,使得 s+x 是回文vector<string>getCandidates(conststring&s){vector<string>result;string ss=s;reverse(ss.begin(),ss.end());intn=ss.size();// 枚举分割点 i,如果 reversed[0..i] 是回文,那么可以取 reversed[i+1,n-1] 作为 xfor(inti=-1;i<n;++i){string x=ss.substr(0,i+1);if(isPalindrome(x))result.push_back(ss.substr(i+1));}// 增加一个字符,构成长度为奇数的回文for(chari='a';i<='z';i++)result.push_back(i+ss);returnresult;}intmain(){ios::sync_with_stdio(false);cin.tie(nullptr);string a,b;while(getline(cin,a)){getline(cin,b);// 两个字符串相等则不存在解if(a==b){cout<<"No solution.\n";continue;}if(a.size()>b.size())swap(a,b);vector<string>A=getCandidates(a),B=getCandidates(b);for(autos:B)A.push_back(s);sort(A.begin(),A.end(),cmp);A.erase(unique(A.begin(),A.end()));for(autos:A)if(isPalindrome(a+s)&&!isPalindrome(b+s)||!isPalindrome(a+s)&&isPalindrome(b+s)){cout<<s<<'\n';break;}}return0;}

总结

本题的关键在于理解回文串的结构特性,从而直接构造候选解,避免暴力枚举。通过数学推导,我们发现xxx必须是原字符串反转后的某个后缀,并且该后缀对应的前缀是回文串。基于这一性质,我们可以高效地枚举所有可能的xxx,然后从中筛选出满足条件的最优解。

这种方法的时间复杂度为O(n2)O(n^2)O(n2),空间复杂度为O(n)O(n)O(n),对于n≤1000n \leq 1000n1000的数据范围完全足够。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询