首页 > 其他分享 >CF1512C A-B Palindrome 题解

CF1512C A-B Palindrome 题解

时间:2023-05-19 14:46:18浏览次数:56  
标签:cnt Palindrome putchar CF1512C 题解 void int read

CF1512C A-B Palindrome 题解

洛谷

Codeforces

Description

给出 \(T\) 个只由 01? 组成的字符串 \(s\),将字符串中的 ? 替换成 01 之后形成一个回文串并且恰好有 \(a\) 个 0 和 \(b\) 个 1,无解输出 -1

Solution

首先,若不考虑 ? 原串不为回文串一定无解,输出 -1 即可。

下面进行分类讨论。

  1. 若 \(s_{i}\) 为 ?
  • 当 \(s_{n - i + 1}\) 为 0 时,\(s_{i}\) 也应该为 0,将 \(a\) 减一并将 \(s_{i}\) 改为 0
  • 当 \(s_{n - i + 1}\) 为 1 时,\(s_{i}\) 也应该为 1,将 \(b\) 减一并将 \(s_{i}\) 改为 1
  • 当 \(s_{n - i + 1}\) 为 ? 时,二者相等即可,记录一下个数为 \(cnt\)。
  1. 若 \(s_{i}\) 为 0:当 \(s_{n - i + 1}\) 为 1 时,无解。否则 \(a\) 减一即可(对 \(s_{n - i + 1}\) 的处理在枚举到该位置时处理)。

  2. 若 \(s_{i}\) 为 1:当 \(s_{n - i + 1}\) 为 0 时,无解。否则 \(b\) 减一即可(对 \(s_{n - i + 1}\) 的处理在枚举到该位置时处理)。

当处理完成时,若 \(a < 0\) 或 \(b < 0\) 或 \(a + b \ne cnt\)无解。

若 \(n\) 为奇数:

  • 当 \(s_{\left \lfloor \frac{n}{2} \right \rfloor + 1}\) 为 ? 时,\(a\) 和 \(b\) 只能有一个为奇数,并将 \(s_{\left \lfloor \frac{n}{2} \right \rfloor + 1}\) 替换为对应的数即可。

  • 否则 \(a\) 和 \(b\) 必须均为偶数才有解。

遍历一次,遇到 ? 判断能填哪个就可以了。

Codes

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define max_n 310010
void read(int &p)
{
    p = 0;
    int k = 1;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-')
        {
            k = -1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        p = p * 10 + c - '0';
        c = getchar();
    }
    p *= k;
    return;
}
void write_(int x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
    {
        write_(x / 10);
    }
    putchar(x % 10 + '0');
}
void writesp(int x)
{
    write_(x);
    putchar(' ');
}
void writeln(int x)
{
    write_(x);
    putchar('\n');
}
int T;
int a, b, cnt;
char s[max_n];

signed main()
{
#if _clang_
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
#endif
    read(T);
    while (T--)
    {
        cnt = 0;
        read(a), read(b);
        scanf("%s", s + 1);
        int n = strlen(s + 1);
        if (n != a + b)
        {
            puts("-1");
            continue;
        }
        bool ans = true;
        for (int i = 1; i <= n; i++)
        {
            if (s[i] == '1')
            {
                if (s[n - i + 1] != s[i] && s[n - i + 1] != '?')
                {
                    ans = false;
                    break;
                }
                b--;
            }
            else if (s[i] == '0')
            {
                if (s[n - i + 1] != s[i] && s[n - i + 1] != '?')
                {
                    ans = false;
                    break;
                }
                a--;
            }
            else
            {
                if (s[n - i + 1] == '0')
                {
                    s[i] = '0';
                    a--;
                }
                else if (s[n - i + 1] == '1')
                {
                    s[i] = '1';
                    b--;
                }
                else
                {
                    ++cnt;
                }
            }
        }
        if (!ans)
        {
            puts("-1");
            continue;
        }
        if (a < 0 || b < 0)
        {
            puts("-1");
            continue;
        }
        else if (cnt == a + b)
        {
            if (n % 2 == 1 && s[n / 2 + 1] == '?')
            {
                if ((a & 1) && (!(b & 1)))
                {
                    a--;
                    s[n / 2 + 1] = '0';
                }
                else if ((b & 1) && (!(a & 1)))
                {
                    b--;
                    s[n / 2 + 1] == '1';
                }
                else
                {
                    puts("-1");
                    continue;
                }
            }
            else if ((a & 1) || (b & 1))
            {
                puts("-1");
                continue;
            }
            for (int i = 1; i <= n; i++)
            {
                if (s[i] == '?')
                {
                    if (a)
                    {
                        a -= 2;
                        s[i] = '0';
                        s[n - i + 1] = '0';
                    }
                    else
                    {
                        b -= 2;
                        s[i] = '1';
                        s[n - i + 1] = '1';
                    }
                }
                putchar(s[i]);
            }
            puts("");
        }
        else
        {
            puts("-1");
            continue;
        }
    }
    return 0;
}

标签:cnt,Palindrome,putchar,CF1512C,题解,void,int,read
From: https://www.cnblogs.com/yuhang-ren/p/17415079.html

相关文章

  • CF1512D Corrupted Array 题解
    CF1512DCorruptedArray题解Link洛谷CodeforcesDescription给定一个正整数\(n\)和长度为\(n+2\)的数组\(b\),数组\(b\)是依据如下算法构造的:随机生成一个含有\(n\)个元素的原始数组\(a\);把数组\(a\)赋值给数组\(b\),即\(b_i=a_i(1\lei\len)\);数组\(b\)......
  • 【题解】第五届图灵杯
    //createdon23.05.13目录A.差值B.基础循环结构练习题C.基础计算几何练习题D.永恒悲剧A.差值考虑求长度为\(i\)的答案,肯定是长度\(\geqi\)的后缀,按照字典序排序后,相邻两个求解。所以考虑倒着扫,每次对于\(i\)的后缀找到排名前后第一个后缀,求出两个长度为\(i\)......
  • GYM104363 2023 ccpc 黑龙江省赛 题解
    比赛链接:https://codeforces.com/gym/104363题解:B//bySkyRainWind#include<bits/stdc++.h>#definemprmake_pair#definedebug()cerr<<"Yoshino\n"#definepiipair<int,int>#definepbpush_backusingnamespacestd;typedeflong......
  • ASC8题解
    B:考虑用\(D(n,r)\)表示在\(r\)维空间中有\(n\)个超平面最多形成多少个区域,感觉不是很好做,考虑一下怎么递推。根据在二三维的经验,我们可以得到以下递推式:\(D(n,r)=D(n-1,r)+D(n-1,r-1)\),实际意义就是原来已经有了\(n-1\)个然后再加入一个之后,会与前面的\(n-1\)个超平面在\(r\)维......
  • Html中使用jquery通过Ajax请求WebService接口以及跨域问题解决
    场景VS2019新建WebService/Web服务/asmx并通过IIS实现发布和调用:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130743584在上面实现发布WebService的基础上,怎样在html中通过jquery对接口发起请求和解析数据。注:博客:https://blog.csdn.net/badao_liumang_qiz......
  • abc269_f Numbered Checker 题解
    NumberedChecker题意有一个\(n\timesm\)的方格矩阵,左上角是\((1,1)\),右下角是\((n,m)\),每个方格中都有一个整数,其中\((x,y)\)中的数字为:如果\(x+y\)是奇数,则\((x,y)\)中的数字为\(0\)。否则,\((x,y)\)中的数字为\((x-1)\timesm+y\)。有\(Q\)组询问,每组......
  • CSP-J2022试题题解
    1.乘方原题:https://www.luogu.com.cn/problem/P8813代码:#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintXN=1e9;lla,b,ans=1;intmain(){ cin>>a>>b; for(inti=1;i<=b;i++){ ans*=a; if(ans>XN){ cout......
  • abc270_f Transportation 题解
    Transportation题意有\(n\)个城市,你可以执行以下操作若干次:选择一个没有建机场的城市\(i\),花费\(x_i\)建一个机场。选择一个没有建港口的城市\(i\),花费\(y_i\)建一个港口。还有\(m\)条没有修建的道路,第\(i\)条道路双向连接\(a_i\)和\(b_i\),修建这条道路需要......
  • CF1077E Thematic Contests 题解
    ThematicContests题意有\(n\)个问题,每个问题有一个分类\(a_i\)。现在要举办一些比赛,要求:一场比赛中所有题目的分类相同。所有比赛的分类是互不相同的。第一场比赛的题目数量任意,但从第二场开始,每一场比赛的题目数量都必须是前一场的两倍。求所有比赛的题目数量之和的......
  • abc235_d Multiply and Rotate 题解
    MultiplyandRotate题意给定两个整数\(a\)和\(n\),有一个整数\(x\),初始值为\(1\),有两种操作:将\(x\)变成\(x\timesa\)。在\(x>10\)且\(x\)不是十的倍数的情况下可以执行此操作:将\(x\)当成一个字符串,将其循环右移一次。求最少执行多少次操作能把\(x\)变......