[CSP-S模拟测试]:reverse(模拟)

匿名 (未验证) 提交于 2019-12-03 00:11:01

题目传送门(内部题56)


输入格式

第一行包含一个整数:$T$,表示数据组数。
接下来$T$行,每行包含两个字符串:$a\ b$。


输出格式

对于每组数据,如果存在$c$,输出最长的情况下字典序最大的$c$,否则输出$-1$。


样例

样例输入:

3
AB BA
ABA BAB
AB ABAA

样例输出:

-1
AB
AB


数据范围与提示

样例解释:

对于第一组数据,不存在这样的$c$。
对于第二组数据,$AB$以通过第一种操作到$ABA$,$AB$可以通过第二种操作到$BAB$。
对于第三组数据,$AB$不需要操作即可得到$AB$,$AB$进行两次第二种操作即可得到$ABAA$,并且$AB$是长度最长的字典序最小的满足条件的$c$。

数据范围:

对于$10\%$的数据,$1\leqslant |a|<|b|\leqslant 6$;
对于$30\%$的数据,$1\leqslant |a|<|b|\leqslant 12$;
对于$100\%$的数据,$1\leqslant |a|<|b|\leqslant 2,000,1\leqslant T\leqslant 20$,保证$a,b$都是由$A,B$字符组成。


题解

这道题的难点就在于怎么让其字典序问题。

其实,我们根本不用考虑字典序的问题,这可以从两点看出。

  $\alpha.$题目和样例解释中都说的是字典序最小,然而输出格式中却写的是字典序最大,教练又没有改题,所以这道题不用考虑字典序问题。

  $\beta.$模拟一下过程,一个字符串只能由一种方式转移过来,所以我们也可以找回去,而对于一个长度我们也只能找回去一个串,所以不用考虑字典序问题。

解决了这个问题,就是一道大模拟了,其实可以用$hash$做到线性时间复杂度,但是显然出题人写标程也想偷个懒。

时间复杂度:$\Theta(n^2)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h> using namespace std; char ch1[2001],ch2[2001]; int a[2001],b[2001]; bool judge(){for(int i=1;i<=a[0];i++)if(a[i]!=b[i])return 0;return 1;} int main() { 	int T;scanf("%d",&T); 	while(T--) 	{ 		scanf("%s%s",ch1+1,ch2+1); 		a[0]=strlen(ch1+1); 		b[0]=strlen(ch2+1); 		for(int i=1;i<=a[0];i++)a[i]=ch1[i]-'A'; 		for(int i=1;i<=b[0];i++)b[i]=ch2[i]-'A'; 		if(a[0]>b[0])swap(a,b); 		while(b[0]>a[0]) 		{ 			if(b[b[0]]) 			{ 				b[0]--; 				reverse(b+1,b+b[0]+1); 			} 			else b[0]--; 		} 		while(1) 		{ 			if(judge()) 			{ 				for(int i=1;i<=b[0];i++) 					if(b[i])printf("B"); 					else printf("A"); 				puts(""); 				break; 			} 			if(a[a[0]]) 			{ 				a[0]--; 				reverse(a+1,a+a[0]+1); 			} 			else a[0]--; 			if(b[b[0]]) 			{ 				b[0]--; 				reverse(b+1,b+b[0]+1); 			} 			else b[0]--; 			if(!a[0]&&!b[0]){puts("-1");break;} 		}	 	} 	return 0; } 

rp++

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!