Codeforces Round #607 (Div. 2) (A ~ C)

题目


A - Suffix Three

题意

根据不同的后缀输出不同的国家名字。

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin >> n;
    while(n -- )
    {
        string s;
        cin >> s;
        if(s.size() >= 2)
        {
            string a(s, s.size() - 2, 2);
            if(a == "po") puts("FILIPINO");
        }
        if(s.size() >= 4)
        {
            string a(s, s.size() - 4, 4);
            if(a == "desu" || a == "masu") puts("JAPANESE");
            
        }
        if(s.size() >= 5) 
        {
            string b(s, s.size() - 5, 5);
            if(b == "mnida") puts("KOREAN");
        }
    }

    return 0;
}

B - Azamon Web Services

题意

给出s,c两个串,交换 s 串中的两个字符,使得 s 在严格字典序上比 c 小,存在答案则输出修改后的值,否则输出 “—”

思路

模拟,从前往后依次查找比当前字符最小的,一定要查找到串的最后,因为字典序越大的放的位置越靠后,当前串的字符串最小,只要是找到了一个,之后在进行判断即可。

代码
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin >> n;
    while(n -- )
    {
        string a, b;
        cin >> a >> b;

        if(a < b) cout << a << endl;
        else
        {
            bool flag = false;

            for(int i = 0; i < a.size(); i ++ )
            {
                int t = i;
                for(int j = i + 1; j < a.size(); j ++ )
                {//这个地方一定要小于等于,否则找不到最后
                    if(a[j] <= a[t]) t = j;
                }

                if(a[t] < a[i])
                {
                    swap(a[t], a[i]);
                    if(a < b) flag = true;
                    break;
                }
            }

            if(flag) cout << a << endl;
            else puts("---");
        }
    }

    return 0;
}

C - Cut and Paste

题意

给出一个串s,和一个操作次数x,给定一个光标 l ,当 l = 0时,此时是在s[0]和s[1]中间,也就是说在 s[l] 和 s[l + 1]之间,然后一次操作的过程如下:
Ⅰ:每进行一次操作,l = l + 1;
Ⅱ:令s = 光标的左半部分,串c = 光标的有半部分;
Ⅲ:将 c 串复制到 s 串的后面,复制 s[l - 1] 次
最后输出操作x次之后的 s 串的长度。

思路

模拟,这个题目如果无脑的按照操作做的话,当 x = 1e6的时候,字符串肯定是会爆掉的,根本就存不了这么多数,题目的重是要复制多少次,只要是知道复制多少次,其实是知道 l 前面的数是多少,如果知道了每次复制多少次的话,这个题目就是一个数学题,所以我们要从题目本身出发,x最多是1e6,那么这样的话我们最多存1e6长度的串,就可以进行计算,只要是串的长度到达1e6 就可以进行计算,不用再对串的内容进行操作,其实串的长度也不用非得到1e6,他给多少操作次数,我们的串就到多少长度即可。

代码
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10, mod = 1e9 + 7;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int T;
    cin >> T;
    while(T -- )
    {
        LL n, l = 0;
        string s;
        cin >> n >> s;

        for(int i = 1; i <= n; i ++)
        {
            ++ l;
            string t = s.substr(l, s.size() - l);
            for(int i = 1; i < (int)(s[l - 1] - '0'); i ++) s += t;
            if(s.size() >= n) break;
        }

        LL ans = s.size();

        for(int i = l + 1; i <= n; i ++)
        {
            LL a = i, b = ans - a;
            ans = (i + (b * (s[i - 1] - '0') % mod) + mod) % mod;
        }

        cout << ans << endl;
    }

    return 0;
}

总结

总结本次的比赛,暴露的问题还是很多,B 题,本来思想是对的,但是还有一点没有考虑到,一定要遍历到最后一个才行,否则如果碰到一个最小的就进行交换的话,就不能保证串的字典序最小,当前的字符一定要放到最小的且最后面的字符,才能保证串的字典序最小。
在一个是C题,思路也是没有错误,但是操作的时候还是有错误,一开始为了显的清楚一些,增加了字符串来回复制的操作,耗费了时间,一开始还没有发现,因为在算法上时间复杂度在可控范围内,找了好长时间也没有找到错误,直到大羽老师看穿了错误,简化了代码,将字符串来回赋值的操作去除了,因为字符串的来回赋值是深拷贝,重开一片空间,然后进行复制,而不是直接操作指针,每次都进行上万次复制操作那谁能受得了,还是得感谢大羽老师。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值