- 题意
给定两个仅包含小写字母的字符串 S 和 T,保证 T 仅包含 a、b、c 且这三个小写字母都出现且仅出现一次。现重新排列字符串 S,记重新排列之后的字符串为 S ′ ,我们希望 T 不是 S' ′ 的子序列。请你求出重新排列之后满足该要求的字符串 S ′ ,如果满足要求的 S ′ 有多个,输出字典序最小的那一个。
- 概念理解
子列:在数学中,某个序列的子序列是从最初序列通过去 除某些元素但不破坏余下元素的相对位置(在前或 在后)而形成的新序列。
例如1,1,2,3,3,3,2数列中按从左到右顺序选择取出元素并不一定要连续,且顺序一定。即可以取出1,2,3 或者1,3,2等等
(ps:我就是水太久了连子列概念都忘得差不多了,导致一直wa)
字典排序
不会有人不会吧?建议自行学一下基本排序 最基础的:冒泡,选择,插半等
- 思路
先把s列按字典排序排列完成,再考虑t列是否为子列。显然当t列为abc时,字典排序时的s列若a,b,c都存在,则一定会有其t为子列,其他情况都不用再打乱s列顺序。
#include<stdio.h>
#include<string.h>
int main()
{
int n,i,j,l;
char a[120],b[5],m;
scanf("%d",&n);
getchar();
while(n--)
{
int c[3]={0};
gets(a);
gets(b);
l=strlen(a);
for(i=0;i<l;i++)
{
if(a[i]=='a') c[0]++;
if(a[i]=='b') c[1]++;
if(a[i]=='c') c[2]++;
}
//统计a,c,b元素个数
for(i=0;i<l-1;i++)
{
int flag=1;
for(j=0;j<l-i-1;j++)
{
if(a[j]>a[j+1])
{
m=a[j];
a[j]=a[j+1];
a[j+1]=m;
flag=0;
}
}
if(flag) break;
}
//冒泡排序得到字典序
if(c[0] && c[1] && c[2])
{
if(b[0]=='a' && b[1]=='b' && b[2]=='c')
{
for(i=c[0];i<c[0]+c[2];i++)
a[i]='c';
for(i=c[0]+c[2];i<c[0]+c[1]+c[2];i++)
a[i]='b';
}
}
//t列为abc时且s列有abc元素都存在时的特判和整体交换b,c位置
puts(a);
}
return 0;
}