郑州轻工业大学新生周赛2题解

可写题应该有 A、B、C、D、F、G、H。其他题感兴趣的同学可以看看。

问题 A: 年龄判断

签到题*1

AC代码:

#include 
using namespace std;

int main()
{
     
    int n;
    scanf("%d", &n);
    if (n <= 3)
        printf("infant\n");
    else if (n <= 12)
        printf("child\n");
    else if (n <= 18)
        printf("youngster\n");
    else if (n <= 25)
        printf("youth\n");
    return 0;
}

问题 B: 大象喝水

签到题*2,写法很多,可以公式求答案,也可以while循环暴力求解。

AC代码:

#include 
using namespace std;

int main()
{
     
    double n, h, r;
    scanf("%lf%lf%lf", &n, &h, &r);
    double sum = 0;
    int ans = 0;
    while (sum < n)
    {
     
        ans++;
        sum += r * r * 3.1415926 * h;
    }
    printf("%d\n", ans);
    return 0;
}

问题 C: 并联电阻

签到题*3

AC代码:

#include 
using namespace std;

int main()
{
     
    double n, m;
    scanf("%lf%lf", &n, &m);
    printf("%.2f\n", 1 / (1 / n + 1 / m));
    return 0;
}

问题 D: 学长自救计划

题面有锅,输入的是n、m、pos而不是m、n、pos。

走廊有两头,那么我们考虑走两边逃跑哪边需要的体力更少即可。

顺便先提一下三目运算 ?:

a?b:c,其中a是一个表达式,b和c是一个语句。

等价于 

if(a)
b;
else 
c;

AC代码:

#include 
using namespace std;

int main()
{
     
    int t;
    scanf("%d", &t);
    while (t--)
    {
     
        int n, m, pos;
        scanf("%d%d%d", &n, &m, &pos);
        int ans_left = 0, ans_right = 0;
        for (int i = 1; i <= n; i++)
        {
     
            int a, b;
            scanf("%d %d", &a, &b);
            if (a <= pos) //怪物在左边
                ans_left += b;
            if (a >= pos) //怪物在右边
                ans_right += b;
        }
        printf("%d\n", ans_left < ans_right ? ans_left : ans_right);
    }
    return 0;
}

问题 E: 花海

这题为了代码美观,思路清晰,用到了函数判断素数。感兴趣的同学可以先了解一下函数。本周会讲解。

AC代码:

#include 
using namespace std;

bool ispreme(int x) //函数判断素数
{
     
    int i;
    for (i = 2; i * i <= x; i++)
    {
     
        if (x % i == 0)
            return false;
    }
    return true;
}
int main()
{
     
    int n;
    scanf("%d", &n);
    int i, j, ans = 0;
    for (i = 2; i <= n; i++)
    {
     
        for (j = 2; j * i <= n; j++)
        {
     
            if (ispreme(i) && ispreme(j))
                ans++;
        }
    }
    printf("%d\n", ans);
    return 0;
}

问题 F: 今夕何夕

将节日分别记作1、2、3、4。然后用二维数组a[i][j]记录 第i个人在第j个节日是否有空。

AC代码:

#include 
using namespace std;

char s[10];
int a[10][10];
int main()
{
     
    for (int i = 1; i <= 6; i++)
    {
     
        int n;
        scanf("%d", &n);
        for (int j = 1; j <= n; j++)
        {
     
            scanf("%s", s);
            if (s[0] == 'N' && s[1] == 'Y')
                a[i][1] = 1;
            if (s[0] == 'I' && s[1] == 'L')
                a[i][2] = 1;
            if (s[0] == 'T' && s[1] == 'D')
                a[i][3] = 1;
            if (s[0] == 'N' && s[1] == 'D')
                a[i][4] = 1;
        }
    }
    int ans = 0;
    for (int i = 1; i <= 4; i++)
    {
     
        int sum = 0;
        for (int j = 1; j <= 6; j++)
            sum += a[j][i];
        if (sum == 6) //6个人都有空
        {
     
            ans = i;
            break;
        }
    }
    if (ans == 0)
        printf("What a shame!\n");
    else if (ans == 1)
        printf("New Year\n");
    else if (ans == 2)
        printf("International Labor Day\n");
    else if (ans == 3)
        printf("The Dragon Boat Festival\n");
    else if (ans == 4)
        printf("National Day\n");
    return 0;
}

问题 G: 一个餐厅

本题用到的abs(x)是math.h头文件中的一个函数,返回x的绝对值。

AC代码:

#include 
using namespace std;

int a[310];
int main()
{
     
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    int ans1, ans2 = 100000000000;
    for (int i = n; i >= 1; i--)
    {
     
        int sum = 0;
        for (int j = 1; j <= n; j++)
        {
     
            if (i != j)
            {
     
                sum += abs(a[j] - a[i]);
            }
        }
        if (sum < ans2) //先保证距离最近
        {
     
            ans1 = a[i];
            ans2 = sum;
        }
        else if (sum == ans2) //再保证坐标最小
        {
     
            if (a[i] < ans1)
            {
     
                ans1 = a[i];
            }
        }
    }
    printf("%d %d\n", ans1, ans2);
    return 0;
}

问题 H: acm可好玩了

这题应该可以写,需要注意的是,你的所有输出最终都在一个文件中,测评系统评判你的题目是否正确,就是对应预先就有的标准答案文件和你的输出文件是否一样,因此我们最后一次性输出,和每次输出,最后的效果一致。

AC代码:

#include 
using namespace std;

char s[110];
int main()
{
     
    while (~scanf("%s", s))
    {
     
        int len = strlen(s);
        for (int i = len - 1; i >= 0; i--)
            printf("%c", s[i]);
        printf(" ");
    }
    return 0;
}

问题 I: 小H的面试难题

比较裸的对顶堆动态维护中位数。nlogn可写。

对顶堆详解博客

AC代码:

#include 
using namespace std;

priority_queue<int> q1;
priority_queue<int, vector<int>, greater<int>> q2;
int main()
{
     
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
     
        int temp;
        scanf("%d", &temp);
        q2.push(temp);
        if (i & 1) //奇数
        {
     
            while (q1.size() != q2.size() + 1)
            {
     
                int res = q2.top();
                q2.pop();
                q1.push(res);
            }
            while (q1.top() > q2.top())
            {
     
                int res1 = q1.top();
                int res2 = q2.top();
                q1.pop(), q2.pop();
                q2.push(res1);
                q1.push(res2);
            }
            printf("%d\n", q1.top());
        }
    }
    return 0;
}

问题 J: 最大的差

此题卡时间。

常规解法就是枚举一个ai,再从后面找所有aj,更新答案。

这样时间复杂度是 O ( n 2 ) O(n^2) O(n2),数据范围 100000 100000 100000,会TLE。我们可以预处理一个后缀最小值。这样可以把时间复杂度降到 O ( n ) O(n) O(n)

AC代码:

#include 
using namespace std;

int a[100010];
int pre[100010]; //pre[i]表示区间[i,n]的最小值
int main()
{
     
    int n;
    scanf("%d", &n);
    pre[n + 1] = 2000000001;
    for (int i = 1; i <= n; i++)
    {
     
        scanf("%d", &a[i]);
    }
    for (int i = n; i >= 1; i--)
    {
     
        pre[i] = pre[i + 1] < a[i] ? pre[i + 1] : a[i];
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
     
        ans = ans > a[i] - pre[i] ? ans : a[i] - pre[i];
    }
    printf("%d\n", ans);
    return 0;
}

你可能感兴趣的:(题解)