ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #712 (Div. 2) A,B,C,D,E

2021-04-14 00:01:30  阅读:248  来源: 互联网

标签:arr cout cin int Codeforces 712 num str Div


Codeforces Round #712 (Div. 2) A,B,C,D,E

A - Déjà Vu

题意

给你一个字符串,要你往里面插入一个字符‘a’,让最终的字符串不是回文字符串。

思路

如果字符串是全a就不行,其他情况都行,从头遍历,判断第 n − i − 1 n - i - 1 n−i−1 个字符是不是 a a a ,不是的话就在第 i i i 个字符前插入 a a a 。这样一定能使第 i i i 位不对称。

比赛的时候想复杂了,还判断了回文,并且因为以为只要全部是同一个字符就不行,因此wa了一次。还好很快发现了问题。

代码

赛后写的代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

string str;
int n;

bool isS()
{
    if(str[0] != 'a')
        return 0;
    for(int i = 0; i < n - 1; i++)
    {
        if(str[i] != str[i + 1])
            return 0;
    }
    return 1;
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> str;
        n = str.length();
        if(isS())
        {
            cout << "NO" << endl;
            continue;
        }
        cout << "YES" << endl;
        bool flag = 0;
        for(int i = 0; i < n; i++)
        {
            if(str[n - i - 1] != 'a' && !flag)
            {
                cout << 'a' << str[i];
                flag = 1;
            }
            else
                cout << str[i];
        }
        cout << endl;
    }
    return 0;
}
比赛时写的代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

string str;
int n;

int notP()
{
    for(int i = 0; i < n; i++)
    {
        if(str[i] != str[n - i - 1])
            return i;
    }
    return -1;
}

bool isS()
{
    if(str[0] != 'a')
        return 0;
    for(int i = 0; i < n - 1; i++)
    {
        if(str[i] != str[i + 1])
            return 0;
    }
    return 1;
}

int main(){
    int T;
    cin >> T;
    while(T--)
    {
        cin >> str;
        n = str.length();
        int pos = notP();
        if(pos != -1)
        {
            bool flag = 0;
            cout << "YES" << endl;
            for(int i = 0; i < n; i++)
            {
                if(str[n - i - 1] != 'a' && !flag)
                {
                    cout << 'a' << str[i];
                    flag = 1;
                }
                else
                    cout << str[i];
            }
            cout << endl;
        }
        else
        {
            if(isS())
                cout << "NO" << endl;
            else
            {
                cout << "YES" << endl;
                cout << 'a' << str << endl;
            }
        }
    }
    return 0;
}

B - Flip the Bits

题意

给定两个01串,要求你将第一个串进行操作,每次只能选取该串0和1个数相同的前缀部分取反,判断能否翻转成第二个串。

思路

从尾向前遍历,遇到不同的,如果前缀的01个数相同就翻一下,不同就无解。01的个数以及取反都可以预处理。

犯了很不该犯的细节错误,没初始化以及遍历起点写错,白WA了一发。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtge5ynN-1618328912190)(C:\Users\29039\AppData\Roaming\Typora\typora-user-images\image-20210413200028355.png)]

代码

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

const int N = 3e5 + 10;

char str[N];
int arr[N];
int rev[N];
int ans[N];
int num[2][N];

int main(){
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        cin >> n;
        cin >> str;
        num[0][0] = num[1][0] = 0;
        for(int i = 1; i <= n; i++)
        {
            arr[i] = str[i - 1] == '0' ? 0 : 1;
            rev[i] = str[i - 1] == '0' ? 1 : 0;
            num[0][i] = str[i - 1] == '0' ? num[0][i - 1] + 1 : num[0][i - 1];
            num[1][i] = str[i - 1] == '1' ? num[1][i - 1] + 1 : num[1][i - 1];
        }
        cin >> str;
        for(int i = 1; i <= n; i++)
        {
            ans[i] = str[i - 1] == '0' ? 0 : 1;
        }
        bool flag = 0;
        bool f = 0;
        for(int i = n; i > 0; i--)
        {
            if(f)
            {
                if(rev[i] != ans[i])
                {
                    if(num[0][i] != num[1][i])
                    {
                        flag = 1;
                        break;
                    }
                    f = 0;
                }
            }
            else
            {
                if(arr[i] != ans[i])
                {
                    if(num[0][i] != num[1][i])
                    {
                        flag = 1;
                        break;
                    }
                    f = 1;
                }
            }
        }
        if(flag)
            cout << "NO" << endl;
        else
            cout << "YES" << endl;
    }
    return 0;
}

C - Balance the Bits

题意

给你一个长度为 n n n 的01串,要求你根据这个串构造两个由 ‘ ( ’ 和 ‘ ) ’ 构成长度为 n n n 的字符串,满足两个字符串都是平衡的字符串,并且在1的位置字符相同,0的位置字符不同。其中对于平衡的定义是:该字符串可以通过往括号间插入 + 和 1 使之成为一个合法的数学表达式。

思路

其实意思就是括号一一对应,每个左括号都能找到自己的右括号。

  • 首先是无解的情况,当0的数量为奇数时无解,当字符串的首尾为0时无解。

  • 对于有解的情况,我们把0和1的位置分开存储放在两个vector里。

    • 对于所有的0,找临近的那个0组对形成一对括号,答案串1是‘()’,答案串2是‘)(’,因为0不能出现在边界所以这两种情况都是有解的;
    • 对于所有的1,找最远的那个1组成一对括号,两个答案串都是‘()’。

1不能找临近的,如果找临近的样例都过不去,虽然我不能证明为什么找最远的就没问题……而且很多代码好像都是用奇偶来处理括号配对,我的思路好像有点清奇……

代码

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef pair<int, int> P;

const int N = 3e5 + 10;

char str[N];
char ans1[N];
char ans2[N];
int n;
vector<int> zero;
vector<int> one;

bool ok()
{
    if(n % 2)
        return 0;
    zero.clear();
    one.clear();
    for(int i = 0; i < n; i++)
    {
        if(str[i] == '0')
        {
            if(i == 0 || i == n - 1)
                return 0;
            zero.pb(i);
        }
        else
            one.pb(i);
    }
    if(zero.size() % 2)
        return 0;
    for(int i = 0; i < zero.size(); i += 2)
    {
        ans1[zero[i]] = '(';
        ans1[zero[i + 1]] = ')';
        ans2[zero[i]] = ')';
        ans2[zero[i + 1]] = '(';
    }
    int m = one.size();
    for(int i = 0; i < m / 2; i++)
    {
        ans1[one[i]] = '(';
        ans1[one[m - i - 1]] = ')';
        ans2[one[i]] = '(';
        ans2[one[m - i - 1]] = ')';
    }
    return 1;
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n;
        cin >> str;
        fill(ans1, ans1 + n + 1, 0);
        fill(ans2, ans2 + n + 1, 0);
        if(!ok())
        {
            cout << "NO" << endl;
            continue;
        }
        cout << "YES" << endl;
        cout << ans1 << endl;
        cout << ans2 << endl;
    }
    return 0;
}

D - 3-Coloring

题意

给定 n × n n \times n n×n 的棋盘,只能用三种颜色填充它,每次填充机器会限制其中一种颜色不能使用,要求你在这样的限制下填满棋盘,并且保证没有两个相邻块的颜色相同。

思路

像这样填充:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPmPIJfu-1618328912193)(file:///C:\Users\29039\Desktop\package\qq\791515215\Image\Group2\TX\1J\TX1J4R3_D3{EEYQ`KJP9FJS.png)]

如果1已经填满了图中的位置,机器依然限制接下来的部分不许填2,就在放2的位置填3,反之亦然;因为只有1或2已经放满才会出现这样的情况,所以不可能出现相邻。

其实比赛的时候思路很对,但是不自信否定了这个思路,觉得有可能是有无解的情况的(加上vp时间有点不太好,饭点,饿死了 ≧ ﹏ ≦ 就打了一个小时就去吃饭了)。赛后补题发现思路很对,而且真的不难,有点小可惜。我还是会有自己肯定不会做D题的思维定势…

代码

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef pair<int, int> P;

const int N = 3e5 + 10;

queue<P> que1;
queue<P> que2;

int main()
{
    int n;
    cin >> n;
    int num;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if((i + j) % 2)
            {
                que1.push(P(i, j));
            }
            else
            {
                que2.push(P(i, j));
            }
        }
    }
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            cin >> num;
            if(num == 2)
            {
                if(que1.empty())
                {
                    cout << "3 " << que2.front().first << ' ' <<
                         que2.front().second << endl;
                    que2.pop();
                }
                else
                {
                    cout << "1 " << que1.front().first << ' ' <<
                         que1.front().second << endl;
                    que1.pop();
                }
            }
            else if(num == 1)
            {
                if(que2.empty())
                {
                    cout << "3 " << que1.front().first << ' ' <<
                         que1.front().second << endl;
                    que1.pop();
                }
                else
                {
                    cout << "2 " << que2.front().first << ' ' <<
                         que2.front().second << endl;
                    que2.pop();
                }
            }
            else
            {
                if(que1.empty())
                {
                    cout << "2 " << que2.front().first << ' ' <<
                         que2.front().second << endl;
                    que2.pop();
                }
                else
                {
                    cout << "1 " << que1.front().first << ' ' <<
                         que1.front().second << endl;
                    que1.pop();
                }
            }
        }
    }
    return 0;
}

E - Travelling Salesman Problem

题意

n n n 个点,每个城市有权值 a i a_i ai​、 c i c_i ci​ ,从城市 i i i 到城市 j j j 要花费 m a x ( a j − a i , c i ) max(a_j - a_i, c_i) max(aj​−ai​,ci​)。

求经过所有城市并回来的最小花费。

思路

参考:Codeforces Round #712 (Div. 2)E. Travelling Salesman Problem(大思维)

代码

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
const int N = 1e5 + 10;
typedef long long ll;

struct node
{
    ll a, c;
    bool operator < (const node& obj)
    {
        return a < obj.a;
    }
} arr[N];

int main()
{
    int n;
    cin >> n;
    ll ans = 0;
    for(int i = 0; i < n; i++)
    {
        cin >> arr[i].a >> arr[i].c;
        ans += arr[i].c;
    }
    sort(arr, arr + n);

    ll maxx = arr[0].a + arr[0].c;
    for(int i = 1; i < n; i++)
    {
        ans += max(0ll, arr[i].a - maxx);
        maxx = max(maxx, arr[i].a + arr[i].c);
    }
    cout << ans << endl;
    return 0;
}

总结

好久没有打,感觉实现上有点生疏,很多细节考虑不到。不过好在结果还不错,只是只做到C就开始摸了,D题其实思路最开始就全对但是因为不自信以及心理上摸了所以赛后才写。总之就是还需要多练,以及要自信!

多多包涵,共同进步

标签:arr,cout,cin,int,Codeforces,712,num,str,Div
来源: https://blog.csdn.net/qq_49451105/article/details/115682566

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有