codeforces Round712(dive2)ABC

**

A - Déjà Vu

**
题目大意:
给定一个字符串,判断是否可以添加一个a之后变为一个非回文字符串。
输入:
6
cbabc
ab
zza
ba
a
nutforajaroftuna

输出:
YES
cbabac
YES
aab
YES
zaza
YES
baa
NO
YES
nutforajarofatuna
思路:
字符串分为回文和非回文,非回文的话容易处理。
回文分为头部为a,尾部为a,和头尾非a。
头为a,在头加个a;尾为a,在尾加个a,头尾非a,头尾随便加个a。
只要看首尾就行。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N = 3e5+10;
char s1[N];
//char s2[N];
int len1;
bool check(char *s)
{
    _for(i,0,len1-1)
    {
        if(s[i] != 'a') return false;
    }
    return true;
}
char* insert(char *s ,int x)
{
    _rep(i,len1,x)
    {
        s[i+1] = s[i];
    }
    s[x] = 'a';
    return s;
}
signed main()
{
//    freopen("data.txt","r",stdin);
    IOS;
    int T;
    cin>>T;
    while( T-- )
    {
        int flag=0;
        mst(s1,0);
//        mst(s2,0);
        cin>>s1;
        len1 = strlen(s1);
        if( check(s1) )
        {
            cout<<"NO"<<endl;
            continue;
        }
        cout<<"YES"<<endl;
        _for(i,0,len1-1)
        {
            if( s1[i] == s1[len1-i-1] && (s1[i] !='a'))
            {
                cout<<insert(s1,i)<<endl;
//                flag=1;
                break;
            }
            if( s1[i] != s1[len1-i-1] && s1[len1-i-1]!='a')
            {
                 cout<<insert(s1,0)<<endl;
//                flag=1;
                break;
            }
            if( s1[i] != s1[len1-i-1] && s1[i]!='a')
            {
                 cout<<s1<<"a"<<endl;
                break;
            }
        }

    }
}

B - Flip the Bits

题目大意:
给定两串01字符串s1,s2,可以对有相等数量的0和1的区间,区间只能是s1的前缀,进行全部取反操作,问是否能通过该操作让s1s2相等。
输入:
5
10
0111010000
0100101100
4
0000
0000
3
001
000
12
010101010101
100110011010
6
000111
110100

输出:
YES
YES
NO
YES
NO

思路:
注意是前缀,排在前面的01会经历多次修改,我们不妨从字符串的尾部开始看.
假设字符串长度为n,只要依次进行区间长度为 n , n-1 , n-2 ……1的修改,就可以最终确定是否能改,进行长度为n的修改将第n个元素确定,进行长度为n-1的修改将第n-1个元素确定…….


#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N=3e5+10;
int a[N];
int b[N];
int sum1[N];
int sum2[N];
signed main()
{
    IOS;
    int T;
    cin>>T;
    while(T--)
    {
        int flag=0;
        int n;
        int cnt=0;
        cin>>n;
        string s1,s2;
        cin>>s1>>s2;
        _for(i,1,n)
        {
            a[i]=s1[i-1]-'0';
            b[i]=s2[i-1]-'0';
            sum1[i] =sum1[i-1] + a[i];
            sum2[i] =sum2[i-1] + b[i];
        }
        _rep(i,n,1)
        {
            if(a[i]==b[i] && cnt%2==0)
            {
                continue;
            }
            if(a[i]!=b[i] && (cnt&1)  )
            {
                continue;
            }
            if( sum1[i]*2!=i )
            {
                flag=1;break;
            }
            else
            {
                cnt++;
            }
            if(flag) break;
        }
        if( flag)
        {
            cout<<"NO"<<endl;
        }
        else
        {
            cout<<"YES"<<endl;
        }

    }
}

C. Balance the Bits

题目大意:
给定一串01字符串,构造两个合法括号序列,遇到1时两个序列括号相等,0时括号相反,问是否可以构造并输出。
思路:
特判情况:
两端点有一个0
1数量为奇数,取反必须出现偶数个取反情况
之和后是一定存在两个合法序列,想办法让取反的情况抵消掉,当遇到奇数个“1”和“0”时取“(”,偶数个“0”“1”时取“)”,可以做到平均分配括号(表达的可能不是很到位QAQ)

//dp,矩阵乘
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
//#define int long long
typedef long long ll;

const int N = 2e5+10;
int n;
int a[N];
signed main()
{
    //!!!!!!!!!!!!!!!!!!!!!!
//    freopen("data.txt","r",stdin);
    //!!!!!!!!!!!!!!!!!!!!!!
    IOS;
    int T;
    cin>>T;
    while( T-- )
    {
        mst(a,0);
        cin>>n;
        string s;
        cin>>s;
        int cnt=0;
        _for(i,1,n)
        {
            a[i] = s[i-1]-'0';
            if( a[i] ) cnt++;
        }
        //特判
        if( (cnt&1) || (!a[1]) || (!a[n]))
        {
            cout<<"NO"<<endl;
            continue;
        }

        cout<<"YES"<<endl;
        int mid=(1+n)>>1;

        int num1 =0;
        int num2 =0;
        cout<<"(";
        _for(i,2,n-1)
        {
            if( a[i] )
            {
                num1++;
                if( num1 & 1) cout<<"(";
                else cout<<")";
            }
            else
            {
                num2++;
                if( num2 & 1) cout<<"(";
                else cout<<")";
            }
        }
        cout<<")";
        cout<<endl;

        num1=0;
        num2=0;
        cout<<"(";
        _for(i,2,n-1)
        {
            if( a[i] )
            {
                num1++;
                if( num1 & 1) cout<<"(";
                else cout<<")";
            }
            else
            {
                num2++;
                if( num2 & 1) cout<<")";
                else cout<<"(";
            }
        }
        cout<<")"<<endl;
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值