首页 > 其他 > 详细

2014年NOIP普及组复赛题解

时间:2019-10-27 22:46:56      阅读:115      评论:0      收藏:0      [点我收藏+]

题目涉及算法:

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

珠心算测验

题目链接: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 \times b}B \rceil\) ,然后假设我们当前的答案的分子是 \(A'\) 分母是 \(B'\) ,则当 \(a \le L\) 条件满足是,我们就需要去比较一下 \(\frac{a}{b} \lt \frac{A'}{B'}\) 是否成立,如果成立的话需要更新一下答案为 \(\frac{a}{b}\) ,但是比较实数会损失精度,所以比较规则应该是 \(a \times B' \lt A' \times 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

2014年NOIP普及组复赛题解

原文:https://www.cnblogs.com/codedecision/p/11749198.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!