• 2006年NOIP普及组复赛题解


    题目涉及算法:

    • 明明的随机数:简单模拟;
    • 开心的金明:01背包;
    • Jam的计数法:模拟;
    • 数列:二进制。

    明明的随机数

    题目链接:https://www.luogu.org/problem/P1059
    简单模拟:排序+去重。使用 sort + unique 实现。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[111];
    int main() {
        cin >> n;
        for (int i = 0; i < n; i ++) cin >> a[i];
        sort(a, a+n);
        n = unique(a, a+n) - a;
        cout << n << endl;
        for (int i = 0; i < n; i ++) {
            if (i) putchar(' ');
            cout << a[i];
        }
        cout << endl;
        return 0;
    }
    

    开心的金明

    题目链接:https://www.luogu.org/problem/P1060
    这道题目就是一道裸的01背包,每件物品的体积对应价格,价值对应价格和重要度的乘积。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 30030;
    int V, n, c, p, f[maxn];
    int main() {
        cin >> V >> n;
        while (n --) {
            cin >> c >> p;
            for (int i = V; i >= c; i --)
                f[i] = max(f[i], f[i-c] + c * p);
        }
        cout << f[V] << endl;
        return 0;
    }
    

    Jam的计数法

    题目链接:https://www.luogu.org/problem/P1061
    模拟题,找到单调递增的字符串的下一个排列。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    bool used[26];
    char ch[30];
    int s, t, w;
    
    bool get_next() {
        memset(used, 0, sizeof(used));
        for (int i = 0; i < w; i ++) used[ ch[i] - 'a' ] = true;
        for (int i = w-1; i >= 0; i --) {
            int st = ch[i] - 'a';
            int cnt = 0;
            for (int j = st+1; j <= t; j ++) if (!used[j]) cnt ++;
            if (cnt >= w-i) {
                int id = i;
                for (int j = st+1; j <= t; j ++) {
                    if (!used[j]) {
                        ch[id++] = 'a' + j;
                        if (id >= w) break;
                    }
                }
                return true;
            }
            used[st] = false;
        }
        return false;
    }
    
    int main() {
        cin >> s >> t >> w >> ch;
        s --; t --;
        for (int i = 0; i < 5 && get_next(); i ++)
            cout << ch << endl;
        return 0;
    }
    

    数列

    题目链接:https://www.luogu.org/problem/P1062
    这道题目需要对二进制有一个理解。
    对于 N ,如果我们将其转成二进制数是 (a_ma_{m-1} dots a_1a_0) ,其中 (a_i) 为1表示结果中包含 (k^i)(a_i) 为0表示结果中不包含 (k^i)
    那么我们可以发现:
    N 对应的数 (gt) N-1 对应的数 (gt) N-2对应的数 …… (gt) 1 对应的数 (gt) 0 对应的数。
    所以我们的答案就是N对应的二进制中所有为1的那些位i的 (sum k^i)
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int n, k;
    long long ans;
    long long quick_mi(long long a, int b) {
        if (b == 0) return 1;
        if (b == 1) return a;
        long long t = quick_mi(a, b/2);
        t *= t;
        if (b % 2) t *= a;
        return t;
    }
    int main() {
        cin >> k >> n;
        for (int i = 0; i <= 10; i ++)
            if ( n & (1<<i) )
                ans += quick_mi(k, i);
        cout << ans << endl;
        return 0;
    }
    

    作者:zifeiy

  • 相关阅读:
    金额与数字转化常用实用几个JS方法
    Jdb命令 The Java Debugger
    GLOBAL TEMPORARY TABLE
    安装与配置Nginx
    MySQL二进制安装与密码破解
    基于FPM构建企业RPM包
    安装Tomcat
    nginx配置优化
    DHCP原理及配置(三个小实验)
    DNS主、从服务器的配置
  • 原文地址:https://www.cnblogs.com/codedecision/p/11718661.html
Copyright © 2020-2023  润新知