zoukankan      html  css  js  c++  java
  • 洛谷训练新手村之“过程函数与递归”题解

    P1028 数的计算

    题目链接:https://www.luogu.com.cn/problem/P1028
    题目大意:以递归的方式输出题目描述中的数据方案数。
    解题思路:
    因为是方案数,所以只需要开一个计数器统计一下总共有多少方案即可。我们令 f(n) 返回数为 n 的时候的方案数,不难得出: \(f(n) = 1 + \sum_{i=1}^{ \lfloor \frac{n}2 \rfloor } f(i)\)
    但是需要注意一个细节,我们需要用到 备忘录 (或者称为 记忆化搜索 )的思想,即,如果我已经统计过了 \(f(n)\) ,那么我就在统计的同时将结果记录到一个输出 \(cnt[n]\) 中,下次我直接返回 \(cnt[n]\) 即可。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int a, cnt[1001];
    int f(int num) {
        if (cnt[num]) return cnt[num];
        cnt[num] = 1;
        for (int i = 1; i <= num/2; i ++) cnt[num] += f(i);
        return cnt[num];
    }
    int main() {
        cin >> a;
        cout << f(a) << endl;
        return 0;
    }
    

    P1036 选数

    题目链接:https://www.luogu.com.cn/problem/P1036
    题目大意:找出n个数中选k个数,并且这k个数的和是素数的方案数。
    解题思路: 深度优先搜索 遍历一下即可。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    bool isp(int a) {
        if (a < 2) return false;
        for (int i = 2; i <= a/i; i ++) if (a%i == 0) return false;
        return true;
    }
    int n, k, a[22], cnt;
    void dfs(int id, int m, int sum) {
        if (m == k) {
            if (isp(sum))
                cnt ++;
            return;
        }
        if (id > n) return;
        dfs(id+1, m, sum);
        dfs(id+1, m+1, sum+a[id]);
    }
    int main() {
        cin >> n >> k;
        for (int i = 1; i <= n; i ++) cin >> a[i];
        dfs(1, 0, 0);
        cout << cnt << endl;
        return 0;
    }
    

    P1149 火柴棒等式

    题目链接:https://www.luogu.com.cn/problem/P1149
    题目大意:给你 n 根火柴,问拿这 n 根火柴能够拼出多少个不同的等式。
    解题思路:开一个数组存放每个数对应的火柴棒数量,然后枚举每一个加数和被加数,看看是不是等式刚好使用了 n 根火柴棒(我自己测了一下加数和被加数最大是712,所以我就枚举到了712)。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int refn[10] = { 6,2,5,5,4,5,6,3,7,6 };
    int get_num(int num) {
        if (!num) return 6;
        int ans = 0;
        while (num) {
            ans += refn[num%10];
            num /= 10;
        }
        return ans;
    }
    int n, ans = 0;
    int main() {
        cin >> n;
        for (int i = 0; i < 712; i ++) {
            for (int j = 0; j < 712; j ++) {
                if (get_num(i) + get_num(j) + get_num(i+j)+4 == n) {
                    ans ++;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    

    P1217 [USACO1.5]回文质数 Prime Palindromes

    题目链接:https://www.luogu.com.cn/problem/P1217
    题目大意:找到区间 \([a,b]\) 范围内的所有会问质数。
    解题思路:
    首先考虑枚举区间 \([a,b]\) 内的每一个数,判断是否是回文,是否是质数,但是这样超时了。
    然后考虑优化,只判断奇数,结果还是超时。
    然后考虑有数组存数的每一位(最高 8 位数)以此直接枚举所有的回文数,然后判断是不是素数并且在 \([a,b]\) 范围内。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int t[10], a, b;
    
    int pow10(int a) {  // 求10的a次方
        int s = 1;
        while (a --) s *= 10;
        return s;
    }
    int get_num(int pre, int len) { // 返回前半部分是pre的位数是len的回文数字
        int a = 1, b = 0, c = pre;
        len = len/2;
        for (int i = 0; i < len; i ++) a *= 10;
        while (c) {
            b = b * 10 + c % 10;
            c /= 10;
        }
        return pre * a + b % a;
    }
    bool isp(int a) {
        if (a < 2) return false;
        for (int i = 2; i <= a/i; i ++) if (a % i == 0) return false;
        return true;
    }
    int main() {
        cin >> a >> b;
        for (int len = 1; len <= 8; len ++) {   // 枚举数字位数
            int maxv = pow10((len+1)/2);
            for (int i = maxv/10; i < maxv; i ++) {
                int num = get_num(i, len);
                if (num < a) continue;
                if (num > b) break;
                if (isp(num))
                    cout << num << endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SDK manager打不开解决办法(转载)
    debian安装中文字体
    rtos之定时器实现
    rtos学习之支持多优先级
    RT-Thread 的空闲线程和阻塞延时
    RT-Thread之对象容器
    RT-Thread 之临界段保护
    RT-Thread之线程实现就绪列表
    rtos 学习之链表
    RTOS 的学习之创建线程
  • 原文地址:https://www.cnblogs.com/quanjun/p/11927023.html
Copyright © 2011-2022 走看看