其他分享
首页 > 其他分享> > Codeforces Round #712 (Div. 2) A,B,C,D,E

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

作者:互联网

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 使之成为一个合法的数学表达式。

思路

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

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