[每日一题] [力扣650] 只有两个键的键盘. 2021.9.19

题目描述

最初记事本上只有一个字符 'A' 。你每次可以对这个记事本进行两种操作:

Copy All(复制全部):复制这个记事本中的所有字符(不允许仅复制部分字符)。
Paste(粘贴):粘贴 上一次 复制的字符。
给你一个数字 n ,你需要使用最少的操作次数,在记事本上输出 恰好 n 个 'A' 。返回能够打印出 n 个 'A' 的最少操作次数。

示例 1:

输入:3
输出:3
解释:
最初, 只有一个字符 'A'。
第 1 步, 使用 Copy All 操作。
第 2 步, 使用 Paste 操作来获得 'AA'。
第 3 步, 使用 Paste 操作来获得 'AAA'。

示例 2:

输入:n = 1
输出:0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/2-keys-keyboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路想法

首先要自己明白这是在做一件什么样的事情。
通过一次拷贝,然后可以复制多次。而且每Paste一次都会比原来的数量多一倍。

我使用的方法比较笨,就是通过写一些特殊的例子去找规律。
例子如下:

n = 操作 操作次数
1 不需要操作、自带1个A 0
3 CPP 3
5 CPPPP 5
7 CPPPPPP 7
11 CPPPPPPPPPP 11

那可以通过这个例子发现一些规律,那就是3,5,7,11,都是素数 他们只能不断的粘贴1个A来达到目的。

n = 操作 操作次数
4 CPCP 4
6 CPPCP 5
8 CPCPCP 6

通过这几个例子可以看出 4,6,8都是可以被一些数字整除的。

比如8 可以有如下分解。
它可以被2整除 8/2 = 4 那么此时需要CP两步
4 / 2 = 2 此时需要CP两步
2 需要CP两步,所以总体上是 2 + 2 + 2 = 6 步

再比如333这个数字

333 / 3 = 111 那么此时需要CPP = 3步
111 / 3 = 37 那么此时需要CP(*36) = 37步
所以一共是 37 + 3 + 3 = 43 步。

由此我有代码如下:

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>

class Solution {
public:
    int minSteps(int n) {
        int sum = 0;
        if (n == 1)
            return 0;
        bool can_divid = true;
        while (can_divid) {
            can_divid = false;
            for (int i = 2; i < n; i++) {
                if (n % i == 0) {
                    n /= i;
                    sum += i;
                    can_divid = true;
                    break;
                }
            }
        }
        sum += n;
        return sum;
    }
};

int main(void) {
    Solution s;
    printf("%d %d %d %d %d %d %d\n", s.minSteps(1), s.minSteps(3), s.minSteps(4), s.minSteps(5),
           s.minSteps(6), s.minSteps(333), s.minSteps(100));
    printf("%d\n", s.minSteps(741));
    printf("----------------\n");
    printf("%d\n", s.minSteps(333));
    return 0;
}
posted @ 2021-09-19 22:19  zh30  阅读(62)  评论(0)    收藏  举报