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

    题目涉及算法:

    • ISBN号码:简单字符串模拟;
    • 排座椅:贪心;
    • 传球游戏:动态规划;
    • 立体图:模拟。

    ISBN号码

    题目链接:https://www.luogu.org/problem/P1055
    简单字符串模拟。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    char c, s[20], d;
    int cnt = 1, a;
    int main() {
        cin >> s;
        for (int i = 0; i < 12; i ++) {
            if (s[i] == '-') continue;
            a = (a + cnt * (s[i] - '0') ) % 11;
            cnt ++;
        }
        c = (a == 10) ? 'X' : ('0' + a);
        if (c == s[12]) puts("Right");
        else {
            s[12] = c;
            puts(s);
        }
        return 0;
    }
    

    排座椅

    题目链接:
    首先这道题目就是一个贪心,需要先记录一下每一行和它的下一行间有多少对交头接耳的同学,以及记录一下每一列和它的下一列间有多少交头接耳的同学。
    然后按照同学对数从大到小排一下序。
    但是这里有两个需要注意的地方:

    1. 输出结果的编号是需要从小打到排的;
    2. 洛谷上面的数据有重的(一直WA第8组数据),重的两个也算2组~

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1100;
    int M, N, K, L, D, r1, c1, r2, c2;
    bool vis[maxn][maxn][2];
    vector<int> row_vec, col_vec;
    struct Node {
        int id, cnt;
        Node() {}
        Node(int _id) { id = _id; cnt = 0; }
    } row[maxn], col[maxn];
    bool cmp(Node a, Node b) { return a.cnt > b.cnt || a.cnt == b.cnt && a.id < b.id; }
    int main() {
        cin >> M >> N >> K >> L >> D;
        for (int i = 1; i < M; i ++) row[i] = Node(i);
        for (int i = 1; i < N; i ++) col[i] = Node(i);
        while (D --) {
            cin >> r1 >> c1 >> r2 >> c2;
            if (r1 > r2) swap(r1, r2);
            if (c1 > c2) swap(c1, c2);
            if (c1 == c2) {
                vis[r1][c1][0] = true;
                row[r1].cnt ++;
            }
            if (r1 == r2) {
                vis[r1][c1][1] = true;
                col[c1].cnt ++;
            }
        }
        sort(row+1, row+M, cmp);
        sort(col+1, col+N, cmp);
        for (int i = 1; i <= K; i ++) row_vec.push_back(row[i].id);
        for (int i = 1; i <= L; i ++) col_vec.push_back(col[i].id);
        sort(row_vec.begin(), row_vec.end());
        sort(col_vec.begin(), col_vec.end());
        for (vector<int>::iterator it = row_vec.begin(); it != row_vec.end(); it ++) {
            if (it != row_vec.begin()) putchar(' ');
            cout << (*it);
        }
        cout << endl;
        for (vector<int>::iterator it = col_vec.begin(); it != col_vec.end(); it ++) {
            if (it != col_vec.begin()) putchar(' ');
            cout << (*it);
        }
        cout << endl;
        return 0;
    }
    

    传球游戏

    题目链接:https://www.luogu.org/problem/P1057
    因为每次只能传相邻的,所以我们可以设 (f[i][j]) 表示第 (i) 轮传到编号为 (j(0 le j lt n)) 的同学的方案数。
    则,当 (i = 0) 时,(f[0][0] = 1)
    (i gt 0) 时, (f[i][j] = f[i-1][j] + f[i+1][j]) (这里要注意边界问题,用模运算处理)。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 33;
    int n, m;
    long long f[maxn][maxn];
    int main() {
        cin >> n >> m;
        f[0][0] = 1;
        for (int i = 1; i <= m; i ++) {
            for (int j = 0; j < n; j ++) {
                f[i][j] = f[i-1][(j-1+n)%n] + f[i-1][(j+1)%n];
            }
        }
        cout << f[m][0] << endl;
        return 0;
    }
    

    立体图

    题目链接:https://www.luogu.org/problem/P1058
    这道题目是一道纯模拟问题。
    解题思路:从最后一排(数据中的最上面一行)从左往右处理好最后一排(从小往上放),然后处理的倒数第二排(第2行),……,一直处理到最前面一排(最后一行)。
    同时,在确定每一个方块未知的同时,也要确定一下整个输出矩形的大小范围。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000;
    int n, m, a[maxn][maxn], N, M;
    char s[maxn][maxn];
    void my_copy(char *s, char *t) {
        while (*t) *s ++ = *t ++;
    }
    void paint(int x, int y) {
        my_copy(s[x]+y, "+---+");
        my_copy(s[x+1]+y, "|   |/");
        my_copy(s[x+2]+y, "|   | +");
        my_copy(s[x+3]+y, "+---+ |");
        my_copy(s[x+4]+y+1, "/   /|");
        my_copy(s[x+5]+y+2, "+---+");
    }
    int main() {
        char sss[111];
        cin >> n >> m;
        for (int i = 0; i < n; i ++)
            for (int j = 0; j < m; j ++)
                cin >> a[i][j];
        for (int j = 0; j < m; j ++) {
            for (int i = 0; i < n; i ++) {
                for (int k = 0; k < a[i][j]; k ++) {
                    int sx = (n-1-i) * 2 + 3 * k;
                    int sy = (n-1-i) * 2 + 4 * j;
                    N = max(N, sx + 6);
                    M = max(M, sy + 7);
                    paint(sx, sy);
                }
            }
        }
        for (int i = N-1; i >= 0; i --) {
            for (int j = 0; j < M; j ++) {
                if (!s[i][j]) putchar('.');
                else putchar(s[i][j]);
            }
            putchar('
    ');
        }
        return 0;
    }
    

    代码当中没有使用 strcpy 是因为测试了一下发现它最后会补一个

    作者:zifeiy

  • 相关阅读:
    Python之旅.第八章.网络编程
    Python之旅.第八章网络编程
    Python之旅.第八章.网络编程
    Python之旅.第七章.异常处理
    Python之旅.第六章.面向对象高级
    第五章.面向对象.总结
    Python之旅.第五章.面向对象.
    Python之旅.第五章.面向对象
    Python之旅.第五章.面向对象
    flexible.js
  • 原文地址:https://www.cnblogs.com/codedecision/p/11721238.html
Copyright © 2011-2022 走看看