求倒数第N个字符串

给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,
从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为
{ aaa, aab, aac, …, aaz, aba, abb, …, abz, …, zzz }。这个序列的倒数第27个字符串就是 zyz。
对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
输入格式:
输入在一行中给出两个正整数 L(2 <= L <= 6)和 N(<= 105)。
输出格式:
在一行中输出对应序列倒数第 N 个字符串。题目保证这个字符串是存在的。
输入样例:
3 7417
输出样例:

pat

本题难点在于找到题目的规律,本人第一次做此题时想了半天没处理好,后网搜,整理并详细解释如下:

此题最暴力的解法是逐个存储,但规模稍微大一点就不行,这是有规律的序列,运用规律解题才是真正的解法。那么规律是什么?类似于求十进制数每位上的数字,十进制数的特点是末位上的数字每个9个数字出现一次,所以如果你要得到10进制数的各个位,你必须先保留模10结果,再将原数除以10,循环。此思想用在本题亦是如此,相当于得到“26进制数”的各个位,每个位对应一个字母,这里是将10进制数看成“26进制数”,而得到各个位,各个位的范围在0-25之间,如果要转成字母,只需将a的ASC码加上各个数字即可。需要注意的是,由于模26的结果在0-25之间,如果为0,你得到a,由此可以推出,下标是从0开始的。所以结合本题,下标,即26的L次-N是从0开始的。

本题用到的函数:pow函数,形参类型为double,返回类型为double,若所求下标为M,double型,则M=pow((double)26,(double)L)-N;再将M转为int,这些操作应该适用于几乎所有c/c++编译器,至少轻量级IDE CFREE支持。如果你将这些操作改为 int M=pow((double)26,(double)L)-N,则当L=2,N=649,即M逻辑上为27时,CFREE运行结果为26,但是如果你本题算法正确,提交至PTA平台,g++编译器可以使你的结果运行正确。如果你改为int M=pow(26,L)-N,则CFREE编译器会报错,因为它无法在函数入口将形参自动从int转为double。而上述假设操作在VS环境中均可正确执行,故一般而言,写第一个假设情况。

代码:

#include
#include
using namespace std;
int main()
{
	int L, N,i=0,j;
	cin >> L >> N;
	double M = pow((double)26, (double)L) - N;//求下标为多少
	int m = int(M);//%运算需要int型
	char a[6] = { 0 };
	while (L--)
	{
		a[i++] = 'a' + m % 26;
		m /= 26;
	}
	for (j = i - 1; j >= 0; j--)
		cout << a[j];
	return 0;

原文链接:https://blog.csdn.net/qq_37729102/article/details/80888228

你可能感兴趣的:(求倒数第N个字符串)