在做这道题的时候,通过打表把每一个长度的字符串的的终止位置算出来。。。
比如长度为2的时候,-25后是偶数那么是第一个,直接输出;否则是第二个,再-有多少个2个一对的个数,得到第二个。。简直弱智?
在第二组中 AB=(A-'A')*26+(B-'A') =1 AB是第1对
在第三组中 ABB=(A-'A')*26*26+(B-'A')*26+(B-'A')=27 ABB是第27对
所以我们判断出它是在第几对中,然后计算每一位对应的字母
e.g index=1000, 1000-26=974; 974/2=487对
('?'-'A')*26+'??'-'A'=487 可以算得'??'-'A'的值和 '?'-'A'的值,算出来'??'-'A'=19,'?'-'A'=18 18*26+19=974
974%2==0 所以是最前面那一位 c[0]+'A' (写写小的样例`)
#include<iostream>
#include<string.h>
using namespace std;
long long num[10];
int c[10];
int main()
{
num[0]=1;
for(int i=1;i<10;++i)
num[i]=num[i-1]*26;
for(int i=1;i<10;++i)
num[i]*=i; //字符串长度为i的个数为num[i]个
int index;
while(cin>>index)
{ memset(c,0,sizeof(c)); //没有初始化会导致错误
//记录每一位是多少
int len=1;//记录字符串长度
// memset(c,0,sizeof(c));
for(int i=1;i<=6;++i)
{
if(index>num[i]) //剩余个数足以进入下一个长度
{
++len;
index-=num[i];
}
}
// cout<<index<<endl;
int cnt=index/len; //是长度为len的字符串中的第cnt个
// cout<<cnt<<endl;
int pos=index%len; //POS是第cnt个字符串中的第几位,如果是0 就是上一个字符串中的最后一位,如果是i就是第i位
//cout<<pos<<endl;
for(int i=len-1;cnt;i--) //caution of terminal
{
//if pos==len-1 得到的是最后一位
c[i]=cnt%26;
cnt/=26;
}
//cout<<c[pos]<<endl;
cout<<char(c[pos]+'A')<<endl;// cout<<c[pos+'A']<<endl;
//cout<<char(c[1]+'A')<<endl;
}
}
给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz }。这个序列的倒数第27个字符串就是 zyz。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
仔细观察这两题,核心代码都是一样的
#include<iostream>
using namespace std;
int main()
{
int l,n;
char a[10];
cin>>l>>n;
int M=1;
for(int i=1;i<=l;++i)
M*=26;
int m=M-n; //每个字符串长为l,要求倒数第n个即整数第m个
int i=0;
while(l--)
{
a[i++]='a'+m%26; //每一位对应着%26后的数,第一个%26是最后一个字母,第二个%26是倒数第2个字母
m/=26;
}
i-=1;
for(;i>=0;--i)
{
cout<<a[i];
}
cout<<endl;
return 0;
}