Moo-洛谷


题目描述

image-20220213195952100

image-20220213200022041


解题思路

由题可知,第 k(k>1) 个字符串的组成为 第(k - 1)个字符串 + ‘m’ + (k+2)个 ‘o’ + 第(k - 1)个字符串,不难想到可以用递归简化问题,可以由 n 的值找到目标字符处在前一字符串中或处在当前字符串中间部分(即"mooooooooo…那里"),由此有了两个分支,递归终止条件为 目标字符在当前字符串中间部分 或 目标字符在1-3中 。

要想确定目标字符在当前字符串的位置,就需要知道S(k)的长度,由题意知 S(k)的长度 = 2 * S(k - 1)的长度 + k + 3,据此,再借助matlab工具可以得出当k>=27时,S(k)的长度就超过了109,因此只要用matlab先算出k为1到26的S(k)的长度,如下图

image-20220213212505338

clc,clear
m=26;
a(1)=10;
for i=2:m
    a(i)=2*a(i-1)+i+3;
end
a

由于数据量不多,可以事先将上述数据存入数组中,之后利用该数组,我们就可以知道目标字符在当前字符串的位置,通过递归,也可以推出在上一字符串中的位置,由此便可以得到最终答案。

代码

#include <iostream>
using namespace std;
int a[28] = {3, 10, 25, 56, 119, 246, 501, 1012, 2035, 4082, 8177, 16368, 32751, 65518, 131053, 262124, 524267, 1048554, 2097129, 4194280, 8388583, 16777190, 33554405, 67108836, 134217699, 268435426, 536870881, int(1e9)};
char mo(int ind, int n){
    if (n == 1)	return 'm';
    else if (n == 2 || n == 3)	return 'o';
    int temp = n - a[ind - 1], addmo = ind + 3;
    if (temp <= 0)	return mo(ind - 1, n);
    else if (temp == 1)	return 'm';
    else if (temp <= addmo)	return 'o';
    else	return mo(ind - 1, temp - addmo);
}
int main(){
    int n, ind;
    cin >> n;
    for (ind = 0; a[ind] < n; ind++);
    cout << mo(ind, n) << endl;
    return 0;
}

image-20220213213029371

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值