字符串的最小复制粘贴次数

博客围绕在记事本上通过复制和粘贴操作得到n个'A'的最少步数展开。分析了n从1到6的情况,总结出规律,即除1外最差情况是n步,可通过找出n的因子,以因子为模块个数,算出模块长度,调用递归更新结果。

Initially on a notepad only one character ‘A’ is present. You can perform two operations on this notepad for each step:

Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). 
Paste: You can paste the characters which are copied last time. 
Given a number n. You have to get exactly n ‘A’ on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n ‘A’.

Example 1: 
Input: 3 
Output: 3 
Explanation: 
Intitally, we have one character ‘A’. 
In step 1, we use Copy All operation. 
In step 2, we use Paste operation to get ‘AA’. 
In step 3, we use Paste operation to get ‘AAA’. 
Note: 
The n will be in the range [1, 1000].

当n = 1时,已经有一个A了,我们不需要其他操作,返回0

当n = 2时,我们需要复制一次,粘贴一次,返回2

当n = 3时,我们需要复制一次,粘贴两次,返回3

当n = 4时,这就有两种做法,一种是我们需要复制一次,粘贴三次,共4步,另一种是先复制一次,粘贴一次,得到AA,然后再复制一次,粘贴一次,得到AAAA,两种方法都是返回4

当n = 5时,我们需要复制一次,粘贴四次,返回5

当n = 6时,我们需要复制一次,粘贴两次,得到AAA,再复制一次,粘贴一次,得到AAAAAA,共5步,返回5

通过分析上面这6个简单的例子,我想我们已经可以总结出一些规律了,首先对于任意一个n(除了1以外),我们最差的情况就是用n步,不会再多于n步,但是有可能是会小于n步的,比如n=6时,就只用了5步,仔细分析一下,发现时先拼成了AAA,再复制粘贴成了AAAAAA。那么什么情况下可以利用这种方法来减少步骤呢,分析发现,小模块的长度必须要能整除n,这样才能拆分。对于n=6,我们其实还可先拼出AA,然后再复制一次,粘贴两次,得到的还是5。分析到这里,我想解题的思路应该比较清晰了,我们要找出n的所有因子,然后这个因子可以当作模块的个数,我们再算出模块的长度n/i,调用递归,加上模块的个数i来更新结果res即可,

这里的递归函数值得是已经有n个字符串,下一步应该怎么做,很明了的递归思路,很值得学习和反思

代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
#include <iomanip>

using namespace std;


class Solution 
{
public:
    int minSteps(int n)
    {
        if (n == 1)
            return 0;
        else
        {
            int res = n;
            for (int i = n - 1; i >=2; i--)
            {
                if (n%i == 0)
                    res = min(res, minSteps(n / i) + i);
            }
            return res;
        }
    }
};
题目描述 公司正在开发一种能极高速处理复制与粘贴操作的文本编辑器.作为 JOI 公司的优秀程序员,你被委以核心复制与粘贴处理模块的测试任务. 你必须编写一个精确且高速的程序. 具体任务如下:初始时,文件内容为字符串S. 随后,将执行 N次复制与粘贴操作.第i次操作的含义是: 从位置 A_i到位置B_i的子串被复制,并将复制得到的子串插入到原字符串的位置 C_i处. 这里,“位置x”指从字符串开头起第x个字符之后的位置(位置 0 表示字符串开头). 例如,对于字符串 `copypaste`, 位置 6 表示字符 ‘a’ 与 ‘s’ 之间;位置 9 表示字符 ‘e’ 之后,即字符串末尾. 但需注意,若操作后字符串长度超过M,则从字符串右端开始依次删除字符,直至长度恰好为M. 给定整数K、字符串长度上限M、初始字符串S、操作次数N,以及N次复制与粘贴操作的指令,编写程序,求出操作后字符串的前K个字符. 输入 - 第 1 行:包含两个整数K、M,以空格分隔.其中K表示需输出的字符数,M表示字符串长度的上限. - 第 2 行:包含字符串S,表示初始字符串. - 第 3 行:包含整数N,表示操作次数. - 接下来的N行中,第i行(1 <= i <=N)包含三个整数A_i、B_i、C_i,以空格分隔.表示第i次操作是将从位置A_i到位置B_i的子串复制,并插入到位置C_i处. 输出 输出执行 N 次操作后所得字符串的前 K 个字符,占一行。 样例输入 Copy 2 18 copypaste 4 3 6 8 1 5 2 4 12 1 17 18 0 样例输出 Copy ac 提示 在这个例子中,N=4 次复制与粘贴操作按如下方式进行: 初始字符串为 copypaste。 第 1 次操作中,从位置 3 到位置 6 的子串 ypa 被复制,并在位置 8 插入粘贴,得到字符串 copypastypae。 第 2 次操作中,从位置 1 到位置 5 的子串 opyp 被复制,并在位置 2 插入粘贴,得到字符串 coopyppypastypae。 第 3 次操作中,从位置 4 到位置 12 的子串 yppypast 被复制,并在位置 1 插入粘贴,得到字符串 cyppypastooypyppypastypae,但由于长度超过 M=18,因此从右端开始删除字符,最终得到字符串 cyppypastooypyppypa。 第 4 次操作中,从位置 17 到位置 18 的子串 a 被复制,并在位置 0 插入粘贴,得到字符串 acypypastooypyppypa,但由于长度超过 M=18,因此从右端开始删除字符,最终得到字符串 acypypastooypyppyp。 因此,操作后字符串 acypypastooypyppyp 的前 K=2 个字符为 ac,输出该结果 用c语言实现这个算法
最新发布
11-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值