2022年10月23日周赛ZZULIOJ

2022年10月23日周赛ZZULIOJ

问题 B: 芝华士威士忌和他的小猫咪们


时间限制: 1 Sec  内存限制: 128 MB

题目描述
芝华士威士忌很喜欢带着他的猫咪们一块跑着玩。但是小猫咪们很懒,只有在离他y米以内才愿意和他一块跑。
这天他在坐标为x的位置,他想和他的猫咪们一块跑着玩。
有n个小猫咪,第i个小猫咪在坐标为ai的位置,请问有多少个小猫咪愿意和他一块跑着玩捏
输入
第一行输入三个数 n x y(1 <= n,x,y <=104)

第二行有n个数,表示n个小猫的位置(1 <= ai <=104)
输出
输出一个数表示和他一起跑的小猫咪的数量
样例输入 Copy
6 2 2
1 2 3 4 5 6
样例输出 Copy
4
提示
样例二
输入:
10 5 2
8 5 6 4 8 10 15 2 36 5
输出:
4

代码&注释

#include <stdio.h>
int n, x, y;
int main() {
    scanf("%d%d%d", &n, &x, &y);
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        int kitty;
        scanf("%d", &kitty);
        if (kitty >= x - y && kitty <= x + y) {
            cnt++;
        }
    }
    printf("%d", cnt);
    return 0;
}

问题 C: 愿我的弹雨能熄灭你们的痛苦

时间限制: 1 Sec  内存限制: 128 MB
提交: 926  解决: 462

题目描述
泰拉大陆传来噩耗:能天使马上要退环境啦!但是众所周知,能天使退环境跟我拐天使并没有什么关系。


假设阿能的基础攻击为 n,每蓄力满 m 秒攻击一次。不计攻击时间,每次攻击结束之后立刻重新开始蓄力。

她的技能“过载模式”可以持续15秒,技能期间造成的总伤害为:攻击次数 * (攻击力 - 敌方护甲)。

现在阿能碰到了护甲值高为600的劲敌,由于阿能的伤害太过刮痧(指伤害过低),我们找了ff0来帮助她,又借到了巫恋的娃娃。

已知ff0可以为阿能提升 %a 的攻击力,巫恋的娃娃可以减掉敌人 %b 的护甲。请问你可以帮阿能计算一下她在技能持续的15秒内造成的总伤是多少吗?

数据保证阿能的攻击力大于敌方护甲,结果保留两位小数。

输入
第一行输入两个整数 n,m。(0 < n < 100000, 0 < m < 15)。表示阿能的基础攻击为 n,每蓄力满 m 秒攻击一次

第二行输入两个整数 a, b。(0 < a, b < 100)。表示提高阿能 %a 的攻击力,减少敌人 %b 的护甲。
输出
一个小数表示答案,结果保留两位小数。
样例输入 Copy
1500 1
10 30
样例输出 Copy
18450.00
提示
样例二
输入:
600 2
15 15

输出:
1260.00


代码注释

#include <stdio.h>

int main() {
    int n, m, a, b;
    scanf("%d%d%d%d", &n, &m, &a, &b);
    
    int num = 15 / m;
    double atk = n * (1 + 0.01 * a);
    double arm = 600 * (1 - 0.01 * b);
    
    double ans = num * (atk - arm);
    printf("%.2lf\n", ans);
    return 0;
}

问题 D: 猜糖果游戏

时间限制: 1 Sec 内存限制: 128 MB
提交: 241 解决: 67

题目描述
为了消磨时光,小A打算和他的朋友小B玩猜糖果的游戏。

游戏准备阶段,小A 在桌子上放置三个倒置的杯子,1号杯子放在位置1,2号杯子放在位置2,3号杯子放在位置3。并在其中一个杯子下面藏了一块糖果。

游戏开始以后,小A每次会交换两个杯子的位置(糖果也会随之移动)。
小B并不知道糖果的初始位置,同时他在每次交换后可以去猜一次当前糖果的位置。
小A知道正确答案,在游戏结束后会给小B一个分数,等于她猜对的次数。
给定小A的所有交换和小B的猜测,但是不给定糖果的初始位置,求小B可以获得最高分数。

输入
输入的第一行包含一个整数 N(0 < N <= 100),为交换的次数。

以下 N 行每行描述了游戏的一个回合,包含三个整数 a、b 和 c,表示 小A 交换了位置 a 和 b 的糖果,然后 小B 猜的是位置 c。

所有这三个数均为 1、2、3 之一,并且 a≠b。

输出
一个整数表示小B可以获得的最高分数。
样例输入 Copy
3
1 2 1
3 2 1
1 3 1
样例输出 Copy
2

提示
样例说明:
当糖果初始位置在杯子1下面时,小B猜对了一次(最后一次)

当糖果初始位置在杯子2下面时,小B猜对了两次(开始两次)

当糖果初始位置在杯子3下面时,小B一次也没有猜对。

所以最高分数是2。

代码注释

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const int N = 110;
int main()
{
    int a[4], c[N], n; // a[i]表示i位置上放置的纸杯编号,c[i]表示第i次操作中小B所指位置的纸杯编号
    for (int i = 1; i <= 3; i++)
        a[i] = i;
    scanf("%d", &n); // 为交换的次数
    for (int i = 1; i <= n; i++)
    {
        int x, y, g;
        scanf("%d%d%d", &x, &y, &g); // 对应三个整数 a、b 和 c,表示 小A 交换了位置 a 和 b 的糖果,然后 小B 猜的是位置 c

        int t = a[x];
        a[x] = a[y];
        a[y] = t;
        c[i] = a[g]; // 小B所指向的位置 g上的杯子就是 a[g]
    }

    int maxx = 0;
    for (int i = 1; i <= 3; i++)
    { // 当糖果在第i个位置时
        int sum = 0; // 记录当糖果在第i个位置时,小B猜对的个数
        for (int j = 1; j <= n; j++)
        {
            if (c[j] == i)
                sum++;
        }
        if (sum > maxx)
            maxx = sum;
        // maxx = max(maxx, sum);
    }
    printf("%d", maxx);

    return 0;
}

问题 E: 有趣的次方

时间限制: 1 Sec 内存限制: 128 MB
提交: 1101 解决: 254

题目描述
给你两个整数 x, y。判断是否存在一个非负整数 n, 使得 x <= 2n <= y。

如果存在,输出最小的 2n,如果不存在,输出 -1。
输入
本题为多实例
第一行输入一个正整数 T(1 <= T <= 105),表示数据组数。
接下来 T 行,每行两个整数 x, y(1 <= x <= y <= 109),表示一组询问。
输出
输出 T 行,每行一个整数表示答案。
样例输入 Copy
5
8 21
20 20
123 456
2000 3125
32143 43210
样例输出 Copy
8
-1
128
2048
32768
提示
样例二:
输入
4
800 1000
3000 4000
5000 6000
6000 7000

输出
-1
-1
-1
-1

代码注释

#include <stdio.h>

int a[50];

int main() {
    int T, x, y;

    a[0] = 1;
    for (int i = 1; i <= 30; i++) // 初始化a数组,里面的值依次为 1, 2, 4, 8, 16, ...
        a[i] = 2 * a[i - 1];

    scanf("%d", &T);
    while (T--) {
        scanf("%d%d", &x, &y);

        int f = 0; // 标记是否找到这个2的n次方
        for (int i = 0; i <= 30; i++) {
            if (a[i] >= x && a[i] <= y) {
                printf("%d\n", a[i]);
                f = 1;
                break;
            }
        }
        if (f == 0) printf("-1\n");
    }
    return 0;
}

问题 F: 这是一个简单题

问题 F: 这是一个简单题
时间限制: 1 Sec  内存限制: 128 MB
提交: 568  解决: 68

题目描述
给你一个长度为n的数组a,其中有多少个数,恰好等于集合中另外两个(不同的)数之和?


题目保证数组中的数两两不同。
输入
第一行包含一个整数 n,表示测试题中给出的正整数个数。(n <= 1000)

第二行有 n 个正整数,表示数组a。(1 <= ai <= 10000)
输出
一个整数,表示答案。
样例输入 Copy
4
1 2 3 4
样例输出 Copy
2

提示
样例二
输入
4
3 6 12 11

输出
0

代码&注释

#include <stdio.h>

int pairs_sum[20010];  // pairs_sum[i]表示i出现的次数 (1 <= ai <= 10000) (ai * 2 <=20000)
int a[1010]; // 正整数个数(n <= 1000)

int main() {
    int n;
    scanf("%d", &n);

    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }

    // 找所有的情况
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            pairs_sum[a[i] + a[j]]++;
        }
    }

    // 遍历原数组
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (pairs_sum[a[i]]) {
            ans++;
        }
    }
    printf("%d\n", ans);
    return 0;
}

问题 G: 打印矩阵

观察以下两个矩阵,打印n*n的矩阵。
在这里插入图片描述

输入
一个整数n(1 <= n <= 20)
输出
输出n*n规格的矩阵(每个数字占五列,右对齐)
样例输入 Copy
5
样例输出 Copy
   10   25   24   23   22
   11    2    9    8   21
   12    3    1    7   20
   13    4    5    6   19
   14   15   16   17   18

代码注释

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const int N = 50;
int mtx;
int arr[N][N]; // 将矩阵存储在二维数组中
void solution();

int main()
{
    solution();
    return 0;
}

void solution()
{
    scanf("%d",&mtx);
    int len = 0;
    if (mtx & 1) // 如果是奇数,先将1放入arr数组
    {
        len = 3;
        arr[mtx / 2 + 1][mtx / 2 + 1] = 1;
    }
    else // 如果是偶数,先将1 2 3 4 放入数组
    {
        len = 4;
        arr[mtx / 2][mtx / 2] = 1, arr[mtx / 2 + 1][mtx / 2] = 2, arr[mtx / 2 + 1][mtx / 2 + 1] = 3, arr[mtx / 2][mtx / 2 + 1] = 4;
    }

    for (int i = len; i <= mtx; i += 2) //  表示接下来我们将要扩充的是边长为 i 的矩阵
    {
        for (int x = 1; x <= i; x++) // 每行依次扩充
        {
            int row = x + (mtx - i) / 2;						   // row表示当前行在a数组中的行下标
            arr[row][(mtx - i) / 2 + 1] = (i - 2) * (i - 2) + x; // 计算每一行的第一个数
            // (i - 2) * (i - 2) inner matrix's max value, e.g 4. (通过计算内层 + 1得到外层matrix的首项的值)
            // x will x++, row also. (row 随着 x 增大而增大,依次得到每一行的第一个数的值)
            arr[row][(mtx - i) / 2 + i] = i * i - i + 2 - (x - 1);//最后一个数也要增加
            // (mtx - i) / 2 得到 当前matrix 到边界的距离, 该距离 + i 为当前行最后一个数的下标,(i, 也就是len,当前matrix边长)
            // i * i - i + 2 得到当前矩阵当前行的最后一个数的值,如 14
            if (x == 1) // 继续第一行的添加(补全其他空(首位,末尾,上边代码已经添加了))
            {
                int val = i * i - i + 2 + 1; // i * i - i + 2 得到当前矩阵当前行的最后一个数的值,比如14,再加1得到15
                for (int j = i - 1 + (mtx - i) / 2; j > 1 + (mtx - i) / 2; j--)
                    arr[row][j] = val, val++; // 矩阵下标是从 1 开始的 (当 matx = 6, i = 4 时, val = 15, j初始值为4
            }
            else if (x == i) // 继续添加最后一行的空缺位
            {
                int val = i * i - i + 2 - x; // 矩阵下标是从 1 开始的
                for (int j = i - 1 + (mtx - i) / 2; j > 1 + (mtx - i) / 2; j--)
                    arr[row][j] = val, val--;
            }
        }
    }

    for (int i = 1; i <= mtx; i++) // 输出答案 
    {   // 矩阵下标是从 1 开始的
        for (int j = 1; j <= mtx; j++)
            printf("%5d", arr[i][j]);
        printf("\n");
    }
}

问题 H: scz的简单考验

时间限制: 1 Sec 内存限制: 128 MB
提交: 98 解决: 18

题目描述
scz如今已经顺利进入高中啦!
他天资聪明,他的迷弟小明想考验他。

现在给出一个分数,要求把它转换为以下形式
在这里插入图片描述

其中的每一步转换都是一个整数 加一个 真分数。

scz听了以后说“太简单了!”就潇洒离开,留下小明一个人在风中凌乱,现在就请你帮助小明解决问题吧~

输入
输入两个整数 P 和 Q (0 <= P, Q <= 107)

保证输入的分数合法且都可以写成有限长度的上述形式
输出
输出一行,格式见样例
样例输入 Copy
103 24
样例输出 Copy
103/24 = 4+1/{3+1/{2+1/3}}

提示
样例二:
输入 23 79
输出 23/79 = 0+1/{3+1/{2+1/{3+1/3}}}

样例三:
输入 6 3
输出 6/3 = 2

代码注释

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

int p, q, a[100010];

int main() {
    scanf("%d%d", &p, &q);
    if (p % q == 0) {
        printf("%d/%d = %d\n", p, q, p / q);
    }
    else {
        int idx = 0;
        a[0] = p / q;
        printf("%d/%d = %d", p, q, a[0]);

        int x = p % q, y = q;
        while (x != 1) {
            p = y, q = x; // 交换位置,即换成倒数形式
            if (p % q == 0) {
                x = 1, y = p / q;
                break;
            }
            a[++idx] = p / q;
            x = p % q, y = q;
        }
        for (int i = 1; i <= idx; i++) {
            printf("+1/{%d", a[i]);
        }
        printf("+1/%d", y);
        for (int i = 1; i <= idx; i++)
            printf("}");
        printf("\n");
    }
    return 0;
}

问题 I: 完美区间

时间限制: 1 Sec 内存限制: 128 MB
提交: 80 解决: 13

题目描述
给定长度为n的一个数组a,我们规定一个完美区间 [l,r]
满足 a[l] & a[l+1] & a[l+2] & … & a[r] 的运算结果为偶数。
(包含偶数,就可以称为完美区间?)
其中 & 为按位与操作。
求这个数组内共有几个完美区间。
由于结果可能很大,请使用 long long

输入
第一行输入一个整数n (1<= n <= 2*105),表示数组的长度。
第二行输入长度为n的数组a,(ai <= 10000);
输出
输出一个整数表示数组的个数。

样例输入 Copy
2
1 6
样例输出 Copy
2

提示
样例说明:
区间[1,2]和区间[2,2]是完美区间。

代码&注释




// 纯奇数则不是完美空间吧
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const int N = 5e5 + 10;
typedef long long LL;
LL oddNumArr[N];
int main()
{
    LL n, i, index = 0, len, sum;
    scanf("%lld", &n);
    LL x;
    for (i = 1; i <= n; i++)
    {
        scanf("%lld", &x);
        if (x & 1)
            oddNumArr[++index] = i; // 将所有奇数的下标都存在数组中
    }

    len = 1, sum = (n + 1) * n / 2; // sum 记录全部区间个数,len 记录当前区间(全是奇数)的长度
    for (i = 1; i <= index; i++)
    {
        if (i != index) // 如果 i 不是 oddNumArr 数组的最后一个,则看 oddNumArr[i] 和 oddNumArr[i + 1] 的下标是否连续
        {
            if (oddNumArr[i] == oddNumArr[i + 1] - 1)
                len++; // 连续的话,len + 1
            else
                sum = sum - (len * (len + 1) / 2), len = 1; // 不连续的话,先将前面一块的总个数剪掉, len = 1
        }
        else
        {
            sum = sum - (len * (len + 1) / 2);
        }
    }
    printf("%lld", sum);
    return 0;
}

问题 J: 是狂热的小迷妹一枚吖~

时间限制: 1 Sec 内存限制: 128 MB
提交: 53 解决: 21

题目描述
“说实话,最喜欢你了;因为长得好看,所以最喜欢你了。
你的性格,我最喜欢了;虽然不太清楚,但是最喜欢了。”

yzgg作为acm队实力与颜值的担当,狂热的迷妹给他写了封情书并打算追他,但是yzgg的数学很好,她的数学很差,所以打算狂刷数学题来缩短他们之间的差距
这天她遇到了个数学题:

有 n 个数字,把 n 个数划分为任意 m 个集合使得:
1、每个数都要在 m 个的集合中的一个集合里
2、每个集合不能为空

使得最后分成的 m 个集合的值的和最小,每个集合的值为:这个集合中所有数的乘积的 m 次方。

由于答案可能十分大所以只需要求这个值的和模 109 +7 之后的结果就可以了

你能帮迷妹做出这道题吗?

输入
第一行输入一个数n(1 <= n <= 10)

第二行输入n个数(数的范围:1~109)
输出
输出最小的值的和(结果对 109 +7 取模)
样例输入 Copy
2
1 2
样例输出 Copy
2

代码&注释




#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
    int n;
    scanf("%d", &n);
    long long mod = 1e9 + 7;
    long long x, sum = 1;
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &x);
        sum = sum * x % mod; // 这是放在一个集合里了吗?
    }
    printf("%lld", sum);
    return 0;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值