2021-12-19【Educational Codeforces Round 119 (Rated for Div. 2)】【题解A-E】

A. Equal or Not Equal

题目描述

你有 n 个正整数 a1,a2,…,an 排列成一个圆圈。对于每对相邻的数字(a1 和 a2,a2 和 a3,…,an−1 和 an,以及 an 和 a1),您写下:这对数字中的数字是否相等。

不幸的是,您丢失了一张带有数组 a 的纸。此外,您担心即使有关相邻元素相等的信息也可能不一致。所以,您想知道:是否有任何数组 a 与您所掌握的关于对应对的相等或不相等的信息一致?

输入
第一行包含一个整数 t (1≤t≤1000)——测试用例的数量。接下来是 t 个案例。

每个测试用例的第一行也是唯一的一行包含一个由字符 E 和/或 N 组成的非空字符串 s。 s 的长度等于数组 n 的大小并且 2≤n≤50。对于从 1 到 n 的每个 i:

如果 si= E 则 ai 等于 ai+1(对于 i=n,an=a1);
如果 si= N,则 ai 不等于 ai+1(对于 i=n,an≠a1)。
输出
对于每个测试用例,如果可以选择与您知道的 s 中的信息一致的数组 a,则打印 YES。否则,打印 NO。

可以证明,如果存在某个数组a,则存在一个由小于或等于109的正整数组成的数组a。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

const int maxn=1e6+5;
void solve(){
    string s;
    cin >> s;
    int n = s.size();
    int cnt = 0;
    //错误理解
    // if(s[n-2]=='N')
    //     cout << "YES\n";
    // else if(s[n-2]=='E'){
    //     for (int i = 0; i < n - 2;i++){
    //         if(s[i]=='N')
    //             cnt++;
    //     }
    //     if(cnt%2==0){
    //         if(s[n-1]=='N')
    //             cout << "NO\n";
    //         else
    //             cout << "YES\n"; 
    //     }       
    //     else
    //         cout << "NO\n";
    //         // if(s[n-1]=='E')
    //         //     cout << "NO\n";
    //         // else
    //         //     cout << "YES\n"; 
    // }
    for (int i = 0; i < n;i++){
        if(s[i]=='N')
            cnt++;
    }
    if(cnt==1)
        cout << "NO\n";
    else
        cout << "YES\n";
}

int main(){
    ios::sync_with_stdio(0);
    int t;
    cin >> t ;
    while(t--){
         solve();
    }
    return 0;
}

B. Triangles on a Rectangle

题目描述

在平面上绘制一个矩形,其对角位于 (0,0) 和 (w,h) 且边与轴平行。

给定一个格点列表,每个点都位于矩形的一侧,但不在其角上。此外,矩形的每一边至少有两个点。

你的任务是以这样的方式选择三个点:

它们中的两个正好属于矩形的同一边;
由它们形成的三角形的面积是最大的。
打印这个三角形的两倍面积。可以证明,任何由格点组成的三角形的两倍面积总是一个整数。

输入
第一行包含一个整数 t (1≤t≤104)——测试用例的数量。

每个测试用例的第一行包含两个整数 w 和 h (3≤w,h≤106)——矩形角的坐标。

接下来的两行包含对两个水平边上的点的描述。首先,一个整数 k (2≤k≤2⋅105)——点数。然后,k 个整数 x1<x2<⋯<xk (0<xi<w) — 按升序排列的点的 x 坐标。第一行的 y 坐标为 0,第二行的 y 坐标为 h。

接下来的两行包含对两个垂直边上的点的描述。首先,一个整数 k (2≤k≤2⋅105)——点数。然后,k 个整数 y1<y2<⋯<yk (0<yi<h)——点的 y 坐标按升序排列。第一行的 x 坐标为 0,第二行的 x 坐标为 w。

所有测试用例中所有边的总点数不超过 2⋅105。

输出
对于每个测试用例,打印一个整数——由三个点形成的三角形的最大面积的两倍,其中三个点恰好属于同一边。

code:


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

const int maxn=1e6+5;
void solve(){
    int x, y;
    cin >> x >> y;
    ll maxx = 0;
    ll maxy = 0;
    for (int i = 0; i < 2;i++){
        int n;
        cin>>n;
        ll a,b;
        ll x;
        for (int j = 0; j < n; j++){
            cin>>x;
			if(j==0)a=x;
			if(j==n-1)b=x ;
        }
        maxx = max(maxx, (b-a));
    }
    for (int i = 0; i < 2;i++){
        int n;
        cin>>n;
        ll a,b;
        ll x;
        for (int j = 0; j < n; j++){
            cin>>x;
			if(j==0)a=x;
			if(j==n-1)b=x ;
        }
        maxy = max(maxy, (b-a));
    }
    ll num = max(maxx * y, maxy * x);
    cout << num << endl;
}

int main(){
    ios::sync_with_stdio(0);
    int t;
    cin >> t ;
    while(t--){
         solve();
    }
    return 0;
}

C. BA-String

题目描述

给定一个整数 k 和一个仅由字符“a”(小写拉丁字母)和“*”(星号)组成的字符串 s。

每个星号应替换为几个(从 0 到 k 包括在内)小写拉丁字母“b”。不同的星号可以替换为不同数量的字母“b”。

替换的结果称为 BA 字符串。

如果两个字符串 a 和 b 具有不同的长度或存在这样的位置 i 使得 ai≠bi,则它们是不同的。

当且仅当以下条件之一成立时,字符串 a 在字典序上小于字符串 b:

  • a是b的前缀,但a≠b;
  • 在 a 和 b 不同的第一个位置,字符串 a 有一个字母在字母表中比 b 中的相应字母出现得更早。

现在考虑所有不同的 BA 字符串并找到其中第 x 个字典序最小的字符串

输入
第一行包含一个整数 t (1≤t≤2000)——测试用例的数量。

每个测试用例的第一行包含三个整数 n 、 k n、k nk x ( 1 ≤ n ≤ 2000 ; 0 ≤ k ≤ 2000 ; 1 ≤ x ≤ 1 0 18 ) x(1≤n≤2000;0≤k≤2000;1≤x≤10^{18}) x1n20000k20001x1018。 n 是字符串 s 的长度。

每个测试用例的第二行是一个字符串 s。它由 n 个字符组成,每个字符都是“a”(小写拉丁字母)或“*”(星号)。

所有测试用例的 n 总和不超过 2000。对于每个测试用例,x 不超过不同 BA 字符串的总数。字符串 s 至少包含一个字符 ‘a’。

输出
对于每个测试用例,打印一个字符串,只包含字符 ‘b’ 和 ‘a’(小写拉丁字母)——第 x 个字典序最小的 BA 字符串。

code:


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int maxn = 1e6 + 5;
void solve()
{
    ll n, k, x;
    cin >> n >> k >> x;
    string s;
    cin >> s;

    if (x == 1 || k == 0)
    {
        string ans = "";
        for (int i = 0; i < n;i++)
        {
            if (s[i] == 'a')
            {
                ans.push_back('a');
            }
        }
        cout << ans << endl;
        return;
    }

    vector<int> v;
    for (int i = n - 1; i >= 0; i--)
    {
        if (s[i] == '*')
        {
            if (i < (n - 1) && s[i + 1] == '*')
            {
                v.back() += k;
            }
            else
            {
                v.push_back(k + 1);
            }
        }
    }

    int m = v.size();
    ll s1 = 1;
    vector<int> cnt(m, 0);
    int i = 0;
    for (; i < m; i++)
    {
        double dx = v[i];
        double nn = (x / dx);
        if (nn <= s1)
        {
            for (int j = i; j >= 0; j--)
            {
                if (j != i)
                    s1 = s1 / v[j];
                cnt[m - j - 1] = (x - 1) / s1;
                x = (x - 1) % s1 + 1;
            }
            break;
        }
        s1 = s1 * v[i];
    }

    int inn = m - 1;
    char prev = 'a';
    string z = "";
    for (int i = n - 1; i >= 0; i--)
    {
        if (s[i] == '*' && prev == '*')
        {
            s.erase(s.begin() + i);
            continue;
        }
        else if (s[i] == '*')
        {
            z = "";
            while (cnt[inn]--)
            {
                z.push_back('b');
            }
            s.erase(s.begin() + i);
            s.insert(i, z);
            inn--;
            prev = '*';
        }
        else
        {
            prev = 'a';
        }
    }
    cout << s << endl;
}

int main()
{
    ios::sync_with_stdio(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}


D. Exact Change

题目描述

一天,一大早,你决定在附近的商店给自己买一袋薯条。这家商店有n种不同口味的薯条。一袋第 i 种口味的价格为 a i a_i ai burles。

这家商店的一些口味可能会用完,所以你到了那里再决定买哪一种。但是这个计划有两个主要缺陷:

你只有 1、2 和 3 个 burles 的硬币;
由于现在是早上,商店会要求您支付确切的零钱,即。 e.如果你选择第 i 种口味,你将不得不支付完全 a i a_i ai burles。
硬币很重,因此您希望总共拿走尽可能少的硬币。这就是为什么您想知道:您应该随身携带的最少硬币总数是多少,以便您可以零钱购买一袋任何口味的薯片?

输入
第一行包含一个整数 t (1≤t≤1000)——测试用例的数量。

每个测试用例的第一行包含单个整数 n (1≤n≤100)——商店中口味的数量。

每个测试用例的第二行包含 n 个整数 a 1 , a 2 , … , a n ( 1 ≤ a i ≤ 1 0 9 ) a_1,a_2,…,a_n (1≤a_i≤10^9) a1,a2,,an(1ai109)——每种口味一袋的成本。

输出
对于每个测试用例,打印一个整数——购买一袋任何口味的零钱所需的最少硬币数。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;

const int maxn=1e6+5;
int a[maxn], b[maxn];
int cnt[3];
void solve(){
    int n;
        cin >> n;
        cnt[0] = cnt[1] = cnt[2] = 0;
        int res = 0, max_a = 0, flag_1 = 0, flag_max = 0;;
        for(int i = 1; i <= n; i ++) {
            cin >> a[i];
            cnt[a[i] % 3] ++; 
            res = max(res, a[i] / 3);
            max_a = max(max_a, a[i]);
            if(a[i] == 1) flag_1 = 1;
           
        }
 
        for(int i = 1; i <= n; i ++) {
            if(max_a - 1 == a[i]) {
                flag_max = 1;
            }
        }
        if(cnt[1] == cnt[2] && cnt[1] == 0) {
            cout << res << '\n';
        }
        else if(cnt[2] == 0 || cnt[1] == 0) {
            cout << res + 1 << '\n';
        }
        else if(max_a % 3 == 0) {
            cout << res + 1 << '\n';
        }
        else if(max_a % 3 == 1 && !flag_1 && !flag_max) {
            cout << res + 1 << '\n';
        }
        else {
            cout << res + 2 << '\n';
        }
}

int main(){
    ios::sync_with_stdio(0);
    int t;
    cin >> t ;
    while(t--){
         solve();
    }
    return 0;
}

E. Replace the Numbers

题目描述

您有一个整数数组(最初为空)。

您必须执行 q 查询。 每个查询属于以下两种类型之一:

"1 x" — 将元素 x 添加到数组的末尾;
"2 x y" — 用 y 替换数组中所有出现的 x。
执行所有查询后找到结果数组。

输入
第一行包含一个整数 q ( 1 ≤ q ≤ 5 ⋅ 1 0 5 ) q (1≤q≤5⋅10^5) q(1q5105)——查询的数量。

接下来的 q 行包含查询(每行一个)。 每个查询属于以下两种类型之一:

" 1 x " ( 1 ≤ x ≤ 5 ⋅ 1 0 5 ) "1 x" (1≤x≤5⋅10^5) "1x"(1x5105);
" 2 x y " ( 1 ≤ x , y ≤ 5 ⋅ 1 0 5 ) "2 x y" (1≤x,y≤5⋅10^5) "2xy"(1x,y5105)
保证至少有一个第一种类型的查询。

输出
在一行中,打印 k 个整数——执行所有查询后的结果数组,其中 k 是第一种类型的查询数。

code:


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int maxn = 1e6 + 5;
int q;
map<int, int> m;
vector<pair<int, int>> qs;
void solve()
{

    cin >> q;
    for (int i = 0; i < q; i++)
    {
        int t;
        cin >> t;
        qs.push_back({-1, -1});
        if (t == 1)
            cin >> qs.back().second;
        else
            cin >> qs.back().first >> qs.back().second;
    }
    vector<int> ans;
    for (int i = q - 1; i >= 0; i--)
    {
        if (m[qs[i].second] == 0)
            m[qs[i].second] = qs[i].second;
        if (qs[i].first == -1)
            ans.push_back(m[qs[i].second]);
        else
            m[qs[i].first] = m[qs[i].second];
    }
    reverse(ans.begin(),ans.end());
    for (auto x : ans)
        cout << x << ' ';
    cout << '\n';
}

int main()
{
    ios::sync_with_stdio(0);
    int t;
    t=1;
    while (t--)
    {
        solve();
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 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
发出的红包

打赏作者

Eternity_GQM

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

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

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

打赏作者

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

抵扣说明:

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

余额充值