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

本文解析了一道关于字符串操作的算法竞赛题,详细介绍了如何通过模拟操作逆向寻找原字符串,最终确定最长且字典序最优的子串。通过具体样例和代码实现,展示了高效的解决策略。

题目传送门(内部题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$。

数据范围:

$\bullet$对于$10\%$的数据,$1\leqslant |a|<|b|\leqslant 6$;
$\bullet$对于$30\%$的数据,$1\leqslant |a|<|b|\leqslant 12$;
$\bullet$对于$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++

转载于:https://www.cnblogs.com/wzc521/p/11586328.html

由于没有直接关于CSP - J复试第二题考点的引用内容,根据常见的CSP - J竞赛情况,CSP - J复试第二题通常会涉及以下考点: ### 数据结构 可能会考察数组、栈、队列、链表等基本数据结构的运用。例如,利用数组存储和处理数据,使用栈来实现括号匹配等相关问题,队列在广度优先搜索(BFS)中也较为常用。 ```python # 简单的栈实现示例 stack = [] stack.append(1) stack.append(2) top_element = stack.pop() ``` ### 算法设计 - **贪心算法**:通过每一步的局部最优选择来达到全局最优解。比如在一些资源分配问题中,每一步都选择当前看起来最有利的分配方式。 ```python # 简单的贪心算法示例:找零钱问题 def greedy_change(amount, coins): coins.sort(reverse=True) count = 0 for coin in coins: while amount >= coin: amount -= coin count += 1 return count coins = [25, 10, 5, 1] amount = 63 print(greedy_change(amount, coins)) ``` - **搜索算法**:深度优先搜索(DFS)和广度优先搜索(BFS)也是常考内容。深度优先搜索通过递归或者栈的方式深入探索节点,广度优先搜索则借助队列按层次遍历节点。 ```python # 简单的深度优先搜索示例 graph = { 'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F'], 'D': [], 'E': [], 'F': [] } visited = set() def dfs(visited, graph, node): if node not in visited: print(node) visited.add(node) for neighbor in graph[node]: dfs(visited, graph, neighbor) dfs(visited, graph, 'A') ``` ### 数学思维 包括数论、组合数学等方面的知识。例如,判断一个数是否为质数、计算排列组合数等。 ```python # 判断一个数是否为质数 def is_prime(n): if n < 2: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False return True print(is_prime(7)) ``` ### 逻辑推理模拟 要求考生根据题目描述模拟实际的操作过程,通过逻辑推理来解决问题。例如,模拟游戏的运行规则,计算游戏的最终结果等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值