2017年NOIP普及组复赛题解

题目涉及算法:

  • 成绩:入门题;
  • 图书管理员:模拟;
  • 棋盘:最短路/广搜;
  • 跳房子:RMQ/二分答案/DP(本人解法)。

成绩

题目链接:https://www.luogu.org/problemnew/show/P3954
入门题,直接计算一下即可。
实现代码如下:

#include <bits/stdc++.h>
using namespace std;
int a, b, c;
int main() {
    cin >> a >> b >> c;
    cout << (a * 2 + b *3 + c * 5) / 10 << endl;
    return 0;
}

图书管理员

题目链接:https://www.luogu.org/problem/P3955
基础题目,实现代码如下:

#include <bits/stdc++.h>
using namespace std;

bool check(int a, int b, int n) {
    int t = 1;
    for (int i = 0; i < n; i ++) t *= 10;
    return a % t == b % t;
}

int n, m, book[1001], x, y;

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i ++) cin >> book[i];
    while (m --) {
        cin >> x >> y;
        int res = -1;
        for (int i = 0; i < n; i++) {
            if (check(book[i], y , x)) {
                if (res == -1) res = book[i];
                else res = min(res, book[i]);
            }
        }
        cout << res << endl;
    }
    return 0;
}

棋盘

题目链接:https://www.luogu.org/problem/P3956
其实我们探索一下1这道问题的本质就是一个迷宫中的最短路,用SPFA可以求解最短路。
这里较为繁琐的就是状态到状态之间的扩展,但是并不难。
实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 15010, maxm = 40040;
int n, m, a[maxn], b[maxn], c[maxn], d[maxn], val[maxm], cnt[maxn];
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i ++) {
        scanf("%d", &val[i]);
        cnt[ val[i] ] ++;
    }
    for (int i = 1; 2+9*i <= n; i ++) {
        int tmp = 0;
        for (int j = 2+9*i; j <= n; j ++) {
            tmp += cnt[j-1-9*i] * cnt[j-1-7*i];
            c[j-i] += cnt[j] * tmp;
            d[j] += cnt[j-i] * tmp;
        }
        tmp = 0;
        for (int j = n-1-9*i; j >= 1; j --) {
            tmp += cnt[j+1+8*i] * cnt[j+1+9*i];
            a[j] += cnt[j+2*i] * tmp;
            b[j+2*i] += cnt[j] * tmp;
        }
    }
    for (int i = 0; i < m; i ++)
        printf("%d %d %d %d\n", a[ val[i] ], b[ val[i] ], c[ val[i] ], d[ val[i] ]);
    return 0;
}

跳房子

题目链接:https://www.luogu.org/problem/P3957
这道题目我用到了如下算法:

  • 线段树求区间最大值;
  • 二分答案;
  • DP求每一次枚举答案g时是否能够找到 \(\ge k\) 的解法。

题解地址:https://www.cnblogs.com/codedecision/p/11753024.html

作者:zifeiy

posted @ 2019-10-28 16:15  codedecision  阅读(1759)  评论(0编辑  收藏  举报