优美的回文串

题源:牛客网
https://www.nowcoder.com/questionTerminal/cf00949583604f8c9f3315fd64236a8c?from=zhnkw&toCommentId=6219448

题目描述:
牛牛在书上看到一种字符串叫做回文串,当一个字符串从左到右和从右到左读都是一样的,就称这个字符串为回文串。牛牛又从好朋友羊羊那里了解到一种被称为优美的回文串的字符串,考虑一个长度为N只包含大写字母的字符串,写出它所有长度为M的连续子串(包含所有可能的起始位置的子串,相同的子串也要计入),如果这个字符串至少有K个子串都是回文串,我们就叫这个字符串为优美的回文串。现在给出一个N,牛牛希望你能帮他计算出长度为N的字符串有多少个是优美的回文串(每个位置都可以是’A’~'Z’的一个。)

输入描述:
输入数据包括三个整数N, M, K(2 ≤ N ≤ 11, 2 ≤ M ≤ N, 0 ≤ K ≤ 11).

示例1
输入
2 2 1

输出
26 长度为2的字符串,它长度为2的子串只有它自身。长度为2的回文串有"AA",“BB”,“CC”…“ZZ”,一共26种。

解法:

首先,对于一个用了n个字母的字符串,通过替换可以替换出A(n,26)种和它模式相同的字符串。
可以这样理解:先从26个字母中挑选n个字母,即有C(n,26)种组合方式,再按字母第一次出现的顺序进行排序,就有C(n,26)*A(n,n) 种字符串。
接下来我们只需要找出一共有多少种模式符合要求,再乘以对应的数量,再相加即可得到答案。

#include<iostream>
#include<cmath>
using namespace std;

int N, M, K;
char str[11];
long long answer = 0;
long long type[12];//表示用了i个字母的排列方式有type[i]种

bool IsElegantPalideome()//判断某个字符串是否是优美回文串
{

	int subNum=0;//子串中是回文串的个数

	for (int i = 0; i < N - M + 1; i++)//有N-M+1个子串,i表示子串的个数
	{
		int flag = 1;
		for (int j = 0; j < M / 2; j++)
		{
			if (str[i + j] != str[i + M - 1 - j])
			{
				flag = 0;
				break;
			}
		}
		if(flag)
			subNum++;
	}
	if (subNum >= K)
		return true;
	else
		return false;
}

void dfs(int len, int num)//len表示待填充的字符个数,num表示已经使用了num个字母
{
	if (len == 0)//不需要再填充字符了
	{
		if (IsElegantPalideome())//这个字符串是优美回文串
		{
			answer += type[num];//这种模式符合要求,通过替换这种模式的字符串共有type[num]种
		}
		return;
	}
	else
	{
		for (int i = 0; i <= num; i++)
		{
			str[len - 1] = 'A' + i;//用i控制字母的变化
			if (i == num)//出现此前没有用到的字母
				dfs(len - 1, num + 1);//所用字符数+1;
			else
				dfs(len - 1, num);
		}
	}
}
int main()
{
	cin >> N >> M >> K;

	type[0] = 0, type[1] = 26;
	for (int i = 2; i < 12; i++)
	{
		type[i] = type[i - 1] * (27 - i);
	}
	dfs(N, 0);
	cout << answer;
}

参考:https://www.jianshu.com/p/69eecb769321

帮到你了就点个赞吧!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windrisess

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值