Educational Codeforces Round 157 (Rated for Div. 2) A-C

文章介绍了三个EducationalCodeforces竞赛中的题目:A.TreasureChest关于最短移动时间,B.PointsandMinimumDistance关于路径最小长度,C.TornLuckyTicket关于票证配对。详细解释了解题思路并给出了AC代码示例。
摘要由CSDN通过智能技术生成

A. Treasure Chest

题目链接

A. Treasure Chest

题目大意

Monocarp 知道宝箱和钥匙的位置都在X轴的正半轴上,Monocarp 在原点,宝箱在 x x x 点,宝箱的钥匙在 y y y 点上,并且 Monocarp 能够搬运 k k k 秒箱子(整个过程只能搬 k k k 秒, 1 ≤ x , y ≤ 100 ; x ≠ y ; 0 ≤ k ≤ 100 1≤x,y≤100; x≠y; 0≤k≤100 1x,y100;x=y;0k100)。
Monocarp 能进行以下操作:

  • 向左或向右 1 1 1 个单位长度(需要 1 1 1 秒)
  • 当前位置拿上钥匙,拿起、放下或打开箱子(需要 0 0 0 秒)

请问 Monocarp 最少需要多少秒打开箱子?

解题思路

只有 3 3 3 种情况:

  • 钥匙在去宝箱的路上,那么就是到宝箱的位置的时间
  • 钥匙在宝箱的后面,可以把宝箱拿到钥匙处 ( x + k ≥ y ) (x+k≥y) (x+ky),那么就是到钥匙位置的时间
  • 钥匙在宝箱的后面,可以把宝箱拿到靠近钥匙处 ( x + k < y ) (x+k<y) (x+k<y),那么就是到钥匙的位置所需时间+折返回到宝箱的位置所需时间

AC代码

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

int main()
{
    int t; cin>>t;
    while(t--)
    {
        int x, y, k;
        cin>>x>>y>>k;
        int ans = x; // 钥匙在去宝箱的路上
        if(y > x) // 钥匙在宝箱后面
        {
            ans = y; // 默认可以将宝箱带到钥匙处
            int d = y-x-k;
            if(d > 0) ans += d; // 需要折返到宝箱处
        }
        cout<<ans<<'\n';
    }
    return 0;
}

B. Points and Minimum Distance

题目链接

B. Points and Minimum Distance

题目大意

给你 2 n 2n 2n 个整数,你需要将它们组成 n ( 2 ≤ n ≤ 100 ) n(2≤n≤100) n(2n100) 个点的坐标(可以相同),然后选择出一条经过这些点的路径(每点至少经过一次),使得该路径的长度最短。
两点间的距离为: ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x_1−x_2|+|y_1−y_2| x1x2+y1y2
如果有多个答案,打印其中任何一个。

解题思路

2 n 2n 2n 个整数排序,前 n n n 个作为 x x x 坐标,后 n n n 个作为 y y y 坐标。

AC代码

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

const int N = 210;
int a[N];

int main()
{
    int t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        for(int i=0; i<2*n; i++) cin>>a[i];
        sort(a, a+2*n);
        int ans = 0;
        for(int i=1; i<n; i++)
            ans += (a[i]-a[i-1]) + (a[n+i]-a[n+i-1]);
        cout<<ans<<'\n';
        for(int i=0; i<n; i++)
            printf("%d %d\n", a[i], a[n+i]);
    }
    return 0;
}

C. Torn Lucky Ticket

题目链接

C. Torn Lucky Ticket

题目大意

票证都是由 1 − 9 1-9 19 对应的字符构成的字符串。
幸运的票证的定义是:

  • 票证的长度为偶数
  • 前半部分的数字之和等于后半部分的数字之和(对半分)

现在,你有 n n n 个残缺的票证 s 1 , s 2 , … , s n s_1,s_2, …,s_n s1,s2,,sn,请你找一找下标 ( i , j ) (i,j) (i,j) 有多少对组成的票证是幸运票证。 ( 1 ≤ i , j ≤ n ) (1≤i,j≤n) (1i,jn)
特别注意: i ≠ j i≠j i=j 时, ( i , j ) (i,j) (i,j) ( j , i ) (j,i) (j,i) 视为不同的一对,当 i = j i=j i=j 时,是同一对。

解题思路

在输入 n n n 个票证时,记录每个票证的第 i i i 位的前缀和,同时利用二维数组记录在相同的票证长度下的所有数字之和相同的个数
遍历每个残缺的票证,然后枚举拼接后的长度得到需要找到另外一个残缺票证的长度,进而找到能与其拼接成幸运票证的残缺票证个数相加得到答案。拼接成幸运的票证大致可以分为 3 3 3 种情况:

  • 直接加上与该残缺票证相同长度且所有数字之和相等的个数(包括了自己和自己拼接)
  • 左拼接:加上长度为 拼接后的长度-该残缺票证长度且数字之和为该残缺票证的数字之和-2*该残缺票证前(该残缺票证长度-拼接后长度/2)个数字之和的个数。
  • 右拼接:加上长度为 拼接后的长度-该残缺票证长度且数字之和为2*该残缺票证的前(拼接后长度/2)个数字之和-该残缺票证的数字之和的个数。

特别注意: 显然枚举得到拼接后的长度要比遍历的残缺票证大,但它的一半得比残缺票证小,这样才好找到符合要求的个数。
不然会重复甚至不好找,就比如拿短的去找比它长的另一半,长的限制条件表面虽然好确定,但是实际上不好找到(长度好确定,但是长的通用数字和不好确定),又得一个个遍历判断一遍。

AC代码

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

const int N = 2e5+10;
int strS[N][7]; // n 个残缺票证及其前缀和
int cnt[6][N]; // 相同长度且相同数字之和的个数

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        char str[10];
        scanf(" %s", str);
        int len = (int)strlen(str);
        for(int j=0; j<len; j++)
            strS[i][j+1] = strS[i][j] + (str[j]-'0');
        strS[i][0] = len;
        int sum = strS[i][len];
        cnt[len][sum]++;
    }
    long long ans = 0;
    for(int i=0; i<n; i++)
    {
        int len = strS[i][0];
        int sum = strS[i][len];
        // 相同长度且相同数字之和拼接
        ans += cnt[len][sum];
        for(int j=1; j<len; j++)
        {
            if(2*j <= len) continue; // 枚举长度
            // 左拼接
            int l = sum - 2*strS[i][len-j];
            if(l > 0) ans += cnt[2*j-len][l];
            //右拼接 sum - 2*(sum-strS[i][j]) ->  2*strS[i][j] - sum
            int r = 2*strS[i][j] - sum;
            if(r > 0) ans += cnt[2*j-len][r];
        }
    }
    printf("%lld", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花生ono

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值