7/11 每日 Codeforces Round #805 div3 A-D题解

最近打cf总是掉分,不过能明显感觉到自己在进步,所以就变成了又菜又爱打的情况。

不过我有把握这个暑假能打上绿名。

昨天的战绩图(QvQ。。。

 确实菜,感觉自己基础也不是很好。

A题和B题我都是直接暴力的,

// Problem: A. Round Down the Price
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.ml/contest/1702/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;

        cin >> n;
        int temp = n;
        int count = 0;
        while (n)
        {
            n /= 10;
            count++;
        }
        int num = 1;

        for (int i = 1; i < count; i++)
        {
            num *= 10;
        }
        printf("%d\n", temp - num);
    }
}
// Problem: B. Polycarp Writes a String from Memory
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.ml/contest/1702/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;
char a[4];
void init()
{
    for (int i = 0; i < 3; i++)
    {
        a[i] = 'A';
    }
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {

        string str;
        cin >> str;
        int count = 0;
        int day = 0;
        int i = 0;
        init();
        int flag = 1;
        int temp = 0;
        set<char> st;
        while (i != str.size())
        {
            st.insert(str[i]);
            if (st.size() == 4)
            {
                st.clear();
                st.insert(str[i]);
                day++;
            }
            i++;
            if (i == str.size() && st.size() == 3)
                day++;
            if (i == str.size() && st.size() < 3 && st.size() != 0)
                day++;
        }
        printf("%d\n", day);
    }
}

今天补了一下C和D,这两题当时我都想到贪心思路了,实现差了很多,都超时了。

C题 https://codeforces.com/contest/1702/problem/C

大意就是一个火车只能从左往右开,有一个数组表示火车站号,火车站可以重复出现。现在给你任意两个火车站号表示起点和终点,让你判断火车能不能开到。

其实是一眼贪心,我当时还是第一次TLE才想到的,思路就是找起点最靠左的位置和终点最靠右的位置。如果这都不能满足的话,那么火车是一定不能开到的。

然后考虑如何存储,map的键值对特性非常符合这道题的要求,所以用两个map来保存起点最靠左的位置和终点最靠右的位置,然后比较即可。

// Problem: C. Train and Queries
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.ml/contest/1702/problem/C
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        int arr[n];
        map<int, int> mi;
        map<int, int> ma;
        for (int i = 1; i <= n; i++)
        {
            int x;
            cin >> x;
            if (mi[x] == 0)//用于保存所有点最左边的位置
                mi[x] = i;
            ma[x] = i;//用于保存所有点最右边的位置
        }
        for (int i = 1; i <= k; i++)
        {
            int l, r;
            cin >> l >> r;
            if (mi[r] == 0 || ma[l] == 0)
                puts("NO");
            else
            {
                if (ma[r] > mi[l])//比较最右边的终点和最左边的起点
                    puts("YES");
                else
                    puts("NO");
            }
        }
    }
}

感觉c题的精髓就在

for (int i = 1; i <= n; i++)
{
            int x;
            cin >> x;
            if (mi[x] == 0)
                mi[x] = i;
            ma[x] = i;
}

这个以前没有见过,学到了。

D题 https://codeforces.com/contest/1702/problem/D​​​​​

D题就是说给你一个字符串由小写字母构成,把a-z用1-26对应起来,然后给你一个整数,让你删除最少的字母,是字符串对应的值小于给定的整数。输出删除后的字符串。

还是一眼贪心,但是删除操作不太好写,比赛的时候一顿乱写,最后果然超时了哈哈哈,主要是我有个地方没有想到,导致我要遍历一个超大的数组,不超时才怪。

我们可以用类似键值对的方法保存小写字母的个数,下标就是小写字母对应的值。这样a[1]的值就是小写字母a的个数。然后我只需要倒着遍历这个大小为26的数组a即可,非常的巧妙。

之后是输出删除后的字符串,这个比较麻烦,可以再开一个大小为26的数组b,再弄个空的字符串,然后遍历给定的字符串,通过比较a,b数组来判断当前的字母是否应该删除,当然这一切的前提是题目说了可以删除任意位置的字母,我的方法是从前面开始删的。

#include <bits/stdc++.h>

using namespace std;

int a[30];
int b[30];

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        memset(a, 0, sizeof(a));//别忘了初始化
        memset(b, 0, sizeof(b));
        string s;
        int p;
        cin >> s >> p;
        int count = 0;
        for (int i = 0; i < s.size(); i++)
        {
            count += s[i] - 'a' + 1;
            a[s[i] - 'a' + 1]++;
        }
        for (int i = 1; i <= 26; i++)
        {
            b[i] = a[i];
        }
        for (int i = 26; i >= 1; i--)
        {
            if (count <= p)
            {
                break;
            }
            while (a[i] > 0 && count > p)
            {
                a[i]--;//删除当前字母一次
                count -= i;
            }
        }
        string w = "";
        for (int i = 0; i < s.size(); i++)
        {
            if (a[s[i] - 'a' + 1] == b[s[i] - 'a' + 1])
            {
                w += s[i];
            }
            else
                a[s[i] - 'a' + 1]++;//待删除的该字母数-1
        }
        cout << w << endl;
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值