1. 乒乓球

来源:NOIP2003提高组 https://ac.nowcoder.com/acm/contest/231/A

算法知识点: 字符串处理,模拟

复杂度:

解题思路:

先将整个比赛情况读取进来,然后依次枚举在11分制和21分制下的比赛结果即可。

  • 在11分制下,一局比赛结束的条件是:某一方达到11分,且分差达到2;
  • 在21分制下,一局比赛结束的条件是:某一方达到21分,且分差达到2;

注意最后如果比分是0:0,也要输出。

C++ 代码:

#include <iostream>
#include <algorithm>

using namespace std;


void work(string str, int score)
{
    int a = 0, b = 0;
    for (int i = 0; i < str.size() && str[i] != 'E'; i ++ )
    {
        if (str[i] == 'W') a ++ ;
        else b ++ ;

        if (max(a, b) >= score && abs(a - b) >= 2)
        {
            printf("%d:%d\n", a, b);
            a = b = 0;
        }
    }
    printf("%d:%d\n", a, b);
}


int main()
{
    string str, s;
    while (cin >> s) str += s;

    work(str, 11);
    puts("");
    work(str, 21);

    return 0;
}

 

2. ISBN号码

来源:NOIP2008提高组 https://ac.nowcoder.com/acm/contest/236/D

算法知识点: 字符串处理,模拟

复杂度:

解题思路:

按照题目中给定的规则,计算出识别码,再判断是否与给定的识别码相同:

  • 如果相同,输出 "Right";
  • 如果不同,输出 正确的字符串。

C++ 代码:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    string str;
    cin >> str;
    int sum = 0;
    for (int i = 0, j = 1; i + 1 < str.size(); i ++ )
        if (str[i] != '-')
        {
            sum += (str[i] - '0') * j;
            j ++ ;
        }
    sum %= 11;
    char c = 'X';
    if (sum < 10) c = '0' + sum;
    if (c == str.back()) puts("Right");
    else
    {
        str.back() = c;
        cout << str << endl;
    }

    return 0;
}

 

3. 立体图

来源:NOIP2008提高组 https://ac.nowcoder.com/acm/contest/236/A

算法知识点: 字符串处理,模拟,坐标变换

复杂度:

解题思路:

首先将一个小正方体的投影画出来:

char box[6][8] = {
    "..+---+",
    "./   /|",
    "+---+ |",
    "|   | +",
    "|   |/.",
    "+---+.."
};

然后为了正确处理遮挡关系,按照从下到上、从后到前、从左到右的顺序画每个小正方体即可。

接下来需要将三维坐标 投影到二维平面上,为了清楚,我们约定三维坐标系的方向如下所示:

QQ截图20190823110842.png

投影到的二维平面的坐标系如下所示:
QQ截图20190823111637.png

我们将三维坐标系中最靠左、前、下的点,和二维坐标系中左下角的点( 为左下角的点)对齐。

然后找规律可以发现二者的映射关系:左下角在 的小立方体,投影之后:

  • 横坐标是
  • 纵坐标是

C++ 代码:

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 500, M = 60;

int n, m;
char box[6][8] = {
    "..+---+",
    "./   /|",
    "+---+ |",
    "|   | +",
    "|   |/.",
    "+---+.."
};

char g[N][N];
int h[M][M];

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            cin >> h[i][j];

    // i = 1, j = n - 1, k = 0: 499, 0
    // i = 1, j = n - 2, k = 0: 497, 2
    // i = 1, j = n - 1, k = 1: 499, 4
    // ...

    // i = 2, j = n - 1, k = 0: 496, 0
    // i = 2, j = n - 2, k = 0: 494, 2
    // ...

    // 499 - (i - 1) * 3 - j * 2
    // j * 2 + k * 4

    for (int i = 0; i < N; i ++ )
        for (int j = 0; j < N; j ++ )
            g[i][j] = '.';

    for (int i = 1; i <= 100; i ++ )
        for (int j = 0; j < n; j ++ )
            for (int k = 0; k < m; k ++ )
                if (h[j][k] >= i)
                {
                    int x = 499 - (i - 1) * 3 - (n - 1 - j) * 2;
                    int y = (n - 1 - j) * 2 + k * 4;

                    for (int a = 0; a < 6; a ++ )
                        for (int b = 0; b < 7; b ++ )
                            if (box[a][b] != '.')
                                g[x - 5 + a][y + b] = box[a][b];
                }

    int x = 0;
    for (int i = 0; ; i ++ )
    {
        bool flag = false;
        for (int j = 0; j < N; j ++ )
            if (g[i][j] != '.')
            {
                flag = true;
                break;
            }

        x = i;
        if (flag) break;
    }

    int y = N - 1;
    for (int i = N - 1; ; i -- )
    {
        bool flag = false;
        for (int j = 0; j < N; j ++ )
            if (g[j][i] != '.')
            {
                flag = true;
                break;
            }

        y = i;
        if (flag) break;
    }

    for (int i = x; i < N; i ++ )
    {
        for (int j = 0; j <= y; j ++ )
            cout << g[i][j];
        cout << endl;
    }

    return 0;
}

 

4. 多项式输出

来源:NOIP2009提高组 https://ac.nowcoder.com/acm/contest/237/D

算法知识点: 字符串处理,模拟

复杂度:

解题思路:

从前往后依次处理每一项,依次考虑符号、系数、x、x的次数:

  • 如果系数是0,则直接continue;
  • 如果不是第一个非零项,且系数是正的,则输出'+';如果系数是负的,则无条件输出'-'
  • 如果系数的绝对值不是1,或者是常数项,则输出系数的绝对值;
  • 如果次数不为0,则输出x
  • 如果次数大于1,则输出次数

C++ 代码:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin >> n;

    bool is_first = true;
    for (int i = n; i >= 0; i -- )
    {
        int a;
        cin >> a;

        if (!a) continue;

        if (!is_first && a > 0) printf("+");
        else if (a < 0) printf("-");
        if (abs(a) != 1 || !i) printf("%d", abs(a));
        if (i) printf("x");
        if (i > 1) printf("^%d", i);

        is_first = false;
    }

    return 0;
}

 
另外,牛客暑期NOIP真题班限时免费报名
报名链接:https://www.nowcoder.com/courses/cover/live/248
报名优惠券:DCYxdCJ