25级新生周赛题解 (二)


高雅的三角形

思路: 根据三角形的边长关系判断是否能构成三角形,先将输入的三个数进行排序。当小的两边相加大于最大的边时,三条边可以构成三角形。

#include <stdio.h>

int main() {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
  
    // 按大到小排序
    if (a < b) {
        int temp = a; a = b; b = temp;
    }
    if (a < c) {
        int temp = a; a = c; c = temp;
    }
  
    if (b + c > a) {
        if (a * a == b * b + c * c) {
            printf("%d", b * c / 2);
        } else {
            printf("%d", a + b + c);
        }
    } else {
        printf("-1");
    }
  
    return 0;
}

牢大大促销

思路: 水题,先计算自己购买能买到的商品数量,再判断最好能选择哪个促销方案。最后输出答案即可。

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    int num = n / 3;
  
    if (num >= 20) {
        num += 5;
    } else if (num >= 11) {
        num += 3;
    } else if (num >= 8) {
        num += 2;
    } else if (num >= 5) {
        num += 1;
    }
  
    printf("%d", num);
    return 0;
}

巴巴博弈

思路: 经典博弈论,巴什博弈。 奇数-奇数=偶数,偶数-奇数=奇数。与偶数互质的数一定是奇数,最终胜利时,胜利状态是奇数。所以无论先手还是后手,轮到自己时如果当前的个数是奇数,最优策略都是只拿走1个,而如果轮到自己时是偶数,则说明必败,任何策略都没用。

#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
  
    if (n % 2 == 0) {
        printf("NO");
    } else {
        printf("YES");
    }
  
    return 0;
}

快来签到领好运

思路: 水题,直接输出即可。

#include <stdio.h>

int main() {
    printf("佛祖保佑你,题题都AC");
    return 0;
}

更典的i-j问题

思路: 题目已经确定是从小到大的数组顺序。但是由于数据范围很大,直接枚举会超时(O(n^2))。因此我们可以使用二分的方法O(n),可以去B站上了解一下(基础算法)进行优化。(下面是关于时间复杂度的博客,有兴趣的可以去学习一下)。 【手把手带你了解时间复杂度和空间复杂度 【超详细】 - CSDN App】 https://blog.csdn.net/tuweizhiwang/article/details/129714398?sharetype=blog&shareId=129714398&sharerefer=APP&sharesource=2501_93999843&sharefrom=link

#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, k;
        scanf("%d %d", &n, &k);
        int a[200010];
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        int ans = 0;
        int l = 1, r = n;
        while (l < r) {
            if (a[l] + a[r] >= k) {
                //因为是有序数组,所以l到r之间的数都可以和a[l]组成大于等于k的数
                ans += (r - l); 
                r--;
            } else {
                //如果a[l]+a[r]<k, 说明a[l]太小, 需要增加l, 才能使a[l]+a[r]>=k
                l++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

有时间就要

思路: 注意过了n天要把现在的这一天也算上。我们可以用数字代表周几,每7天是一个循环,想到我们可以%7,用0表示周日,1表示周一,以此类推。 实现代码:

#include <stdio.h>

int main() {
    int x, y, ans = 0;
    scanf("%d %d", &x, &y);
    for (int i = 0; i < y; i++) {
        int t = x + i;
        if (t % 7 == 1 || t % 7 == 3) {
            continue;
        } else {
            ans += 99;
        }
    }
    printf("%d", ans);
    return 0;
}

决斗场的蜜汁范围1

思路: 超级简单的模拟水题,我们只要判断是否在范围内即可。

#include <stdio.h>

int main() {
    int n, m, h;
    scanf("%d %d %d", &n, &m, &h);
    if (10 + h / 2 >= m && 10 - h / 2 <= m) {
        printf("oh, NO!");
    } else {
        printf("oh, YES!");
    }
    return 0;
}

决斗场的蜜汁范围2

思路: 和上一题差异不大,我们需要先计算出技能到达我们所在x轴的时间,再根据时间算出我们最多移动的y轴距离,最后判断我们是否能到达距离最近的安全点。注意当h为20,速度不是0时,我们无论如何也躲不掉。

#include <stdio.h>

int main() {
    int n, m, h, v;
    scanf("%d %d %d %d", &n, &m, &h, &v);
  
    if (h == 20 && v != 0) {
        printf("oh, NO!");
        return 0;
    }
  
    double t = (double)(200 - n) / (double)v;
    // +1是因为正好在边界也会被击中
    int h1 = 10 + h / 2 + 1; 
    // -1是因为正好在边界也会被击中
    int h2 = 10 - h / 2 - 1; 
    int num = 0;
  
    if (h1 - m < m - h2) {
        num = h1 - m;
    } else {
        // 建议去学一下c++里的max,min函数
        num = m - h2; 
    }
  
    if (t * 2.0 >= num) {
        printf("oh, YES!");
    } else {
        printf("oh, NO!");
    }
  
    return 0;
}

1 条评论

  • 1