zoukankan      html  css  js  c++  java
  • 2014年NOIP普及组复赛题解

    题目涉及算法:

    • 珠心算测验:枚举;
    • 比例简化:枚举;
    • 螺旋矩阵:模拟;
    • 子矩阵:状态压缩/枚举/动态规划

    珠心算测验

    题目链接:https://www.luogu.org/problem/P2141
    因为数据量比较小,直接暴力枚举即可。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 110;
    int n, a[maxn], cnt;
    bool exists[20020];
    int main() {
        cin >> n;
        for (int i = 0; i < n; i ++) cin >> a[i];
        for (int i = 0; i < n; i ++) for (int j = i+1; j < n; j ++) exists[ a[i] + a[j] ] = true;
        for (int i = 0; i < n; i ++) cnt += exists[ a[i] ];
        cout << cnt << endl;
        return 0;
    }
    

    比例简化

    题目链接:https://www.luogu.org/problem/P2118
    只需要从1到L遍历分母 (b) ,根据 (b) 我们能够马上推导出分子 (a = lceil frac{A imes b}B ceil) ,然后假设我们当前的答案的分子是 (A') 分母是 (B') ,则当 (a le L) 条件满足是,我们就需要去比较一下 (frac{a}{b} lt frac{A'}{B'}) 是否成立,如果成立的话需要更新一下答案为 (frac{a}{b}) ,但是比较实数会损失精度,所以比较规则应该是 (a imes B' lt A' imes b)
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    long long A, B, L, ans_a, ans_b;
    int main() {
        cin >> A >> B >> L;
        for (long long b = 1; b <= L; b ++) {
            long long a = (A * b + B - 1) / B;
            if (a > L) continue;
            if (!ans_b || ans_a * b > a * ans_b) {
                ans_a = a;
                ans_b = b;
            }
        }
        cout << ans_a << " " << ans_b << endl;
        return 0;
    }
    

    螺旋矩阵

    题目链接:https://www.luogu.org/problem/P2239
    本题涉及算法:模拟。
    但是一格一格模拟是不对的,因为 (n le 30000)(n^2) 会超时。
    一行一列模拟是可以的,但是一圈一圈模拟更好。
    我们先计算外面走了几个圈(这恰巧是一个等差数列),然后再计算最后走的那一圈(此时最多2行2列),即可获得目的地各自的编号。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    long long n, x, y;
    
    long long get_gezi_number(long long n, long long x, long long y) {
        long long cnt = 0;
        long long d = min( min(x-1, n-x), min(y-1, n-y) );
        cnt = ( 4 * n - 4 + 4 * (n-2*d+2) - 4 ) * d / 2;
        long long x1 = d+1, Y1 = d+1, x2 = n-d, y2 = n-d;
        if (x1 == x) cnt += y-Y1+1;
        else if (y2 == y) cnt += (n-2*d-1) + x-x1+1;
        else if (x2 == x) cnt += 2 * (n-2*d-1) + y2-y+1;
        else cnt += 3 * (n-2*d-1) + x2-x+1;
        return cnt;
    }
    
    int main() {
        cin >> n >> x >> y;
        cout << get_gezi_number(n, x, y) << endl;
        return 0;
    }
    

    子矩阵

    题目链接:https://www.luogu.org/problem/P2258
    本题涉及知识点:状态压缩/枚举/DP。
    题解地址:https://www.cnblogs.com/codedecision/p/11748741.html

    作者:zifeiy

  • 相关阅读:
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
    2020软件工程作业00——问题清单
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    Ubuntu中安装最新 Node.js 和 npm
    英语学习单词篇一
    Golang之内存读写
    Golang之正则表达式的使用
  • 原文地址:https://www.cnblogs.com/codedecision/p/11749198.html
Copyright © 2011-2022 走看看