Codeforces Round #712 (Div. 2)(A-E题解)

场次链接

后悔啊后悔,当天晚上打的时候工作室网炸了,开场五分钟镜像页面才看到题目,A题读完就想到判断最前面和最后面能不能加就行了(字符串渣第一时间没想到直接在原字符串上加,反而去判断s[0]和s[n-1]等不等于’a’然后再写,饶了好大一圈)。写完了准备交的时候原网站也刷出来了,看了一下A过题人数已经有2300了,就没急着交,先去读了一下B和C,吗的读B的时候漏翻了一个prefix,以为可以在任意位置翻转,想了一下卧槽好像很复杂,不对劲啊,这场这么难吗?然后读了下C,发现是个字符串构造,想的时候刷新了一下题目列表,网又炸了,直接跑路 ^ - ^

第二天补题的时候,才发现B是前缀修改…C题在草稿纸上画了一下就发现了规律,D题互动题感觉也是送的,E题也写过类似的题,在知乎上刷ICPC昆明站相关回答的时候看到一个大二的同学这场上了200紫名了,tql,感觉最近cf都比较偏思维,DE的代码量都不大,希望学校网下次给个面子,开局慢五分钟太炸心态了……

A. Déjà Vu
题意:问是否可以在给出字符串中加一个’a’且不变成回文串,并把符合的情况输出出来。

思路:显然如果’a’加在最前面是回文串的话,那么加在最后面肯定就不是了(除了全是a的情况),所以两种情况判断一下如果加完都是回文串就说明是全’a’字符串。

这道有手就行就不贴代码了(其实是因为写的太臭了没脸放:)

B. Flip the Bits
题意:给两个01串,给一个操作可以把长度为x的前缀字符串中的01翻转(0变成1,1变成0),但是这个前缀字符串中的0和1的数量相等,问第一个字符串可不可以通过这个操作变成第二个字符串。

思路:因为操作次数是不限的,所以只要是符合条件的串都可以随意操作,那么每一段01数量相等的终点就是一个节点,节点之间的串就是可以操作的串,判断一下这些串是不是全部相同或者全部不相同即可。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 1000000007
#define stree SegTree[root]
#define lson SegTree[root << 1]
#define rson SegTree[root << 1 | 1]
using namespace std;
const int N = 300005;
char s[N], ss[N];
int main()
{
    int t, n;
    cin>>t;
    while(t--)
    {
        cin>>n>>s>>ss;
        int tem = 0, a = 0, b = 0, fla = 0, cnt1 = 0, cnt0 = 0;
        for(int i = 0;i < n;i++)
        {
            if(s[i]=='1') cnt1++;
            else cnt0++;
            if(s[i]==ss[i])
            {
                a++;
            }
            else if(s[i]!=ss[i])
            {
                b++;
            }
            if(cnt1==cnt0)
            {
                if(a&&b)
                {
                    fla = 1;
                    break;
                }
                else
                {
                    cnt1=cnt0=a=b=0;
                }
            }
        }
        if(b) fla = 1;
        if(fla) printf("NO\n");
        else printf("YES\n");
 
    }
	return 0;
}

C. Balance the Bits

题意:给一个01字符串,让你构造两个由’(‘和’)'组成的合法字符串,1的位置要求两个串相同,0的位置要求两个串不同。

思路:构造题一定要多动手,这道题只要有0和1是偶数次并且起点和终点都是1就必然存在,0的情况一个串可以0跟0一起玩,另一个串就要跟起点和终点的1一起玩了,具体看代码吧,讲起来太复杂,动动手就通了。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 1000000007
#define stree SegTree[root]
#define lson SegTree[root << 1]
#define rson SegTree[root << 1 | 1]
using namespace std;
const int N = 300005;
char s[N];
int main()
{
    int t, n;
    cin>>t;
    while(t--)
    {
        cin>>n>>s;
        string s1, s2;
        int cnt = 0, tem = 1;
        for(int i = 0;i < n;i++)
        {
            if(s[i]=='0') cnt++;
        }
        if(s[0]!='1' || s[n-1]!='1' || cnt%2)
        {
            printf("NO\n");
            continue;
        }
        bool f1 = 1, f2 = 1;
        s1+='(', s2+='(';
        for(int i = 1;i < n-1;i++)
        {
            if(s[i]=='1')
            {
                if(f1)
                {
                    s1+='(';
                    s2+='(';
                    f1 = 0;
                }
                else
                {
                    s1+=')';
                    s2+=')';
                    f1 = 1;
                }
            }
            else
            {
                if(tem <= cnt-2)
                {
                    if(f2)
                    {
                        s1+='(';
                        s2+=')';
                        f2 = 0;
                    }
                    else
                    {
                        s1+=')';
                        s2+='(';
                        f2 = 1;
                    }
                }
                else
                {
                    if(f2)
                    {
                        s1+=')';
                        s2+='(';
                        f2 = 0;
                    }
                    else
                    {
                        s1+='(';
                        s2+=')';
                        f2 = 1;
                    }
                }
                tem++;
            }
        }
        s1+=')', s2+=')';
        cout<<"YES"<<endl<<s1<<endl<<s2<<endl;
    }
	return 0;
}

D. 3-Coloring

题意:互动题,有三个颜色,爱丽丝先选一个颜色,你要在n*n的棋盘上把一个格子涂成除了这个颜色以外的一个颜色,要求相邻边不能相同。

思路:互动题一般都是有规律的构造,找到定式就能很快写出来。这道题有点像下五子棋,斜着交叉放一个颜色,然后剩下的格子就可以另外两个颜色随便放了。代码有点长,但是当时写的时候顺着思路一下就写完了。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 1000000007
#define stree SegTree[root]
#define lson SegTree[root << 1]
#define rson SegTree[root << 1 | 1]
using namespace std;
const int N = 300005;
struct node
{
    int x, y;
}tem;
int main()
{
    int n, x;
    cin>>n;
    queue<node> v1, v2;
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= n;j++)
        {
            if((i+j)%2==0)
            {
                tem.x = i;
                tem.y = j;
                v2.push(tem);
            }
            else
            {
                tem.x = i;
                tem.y = j;
                v1.push(tem);
            }
        }
    }
    for(int i = 1;i <= n*n;i++)
    {
        cin>>x;
        if(x==1)
        {
            if(!v1.empty())
            {
                tem = v1.front();
                v1.pop();
                cout<<"2 "<<tem.x<<" "<<tem.y<<endl;
            }
            else
            {
                tem = v2.front();
                v2.pop();
                cout<<"3 "<<tem.x<<" "<<tem.y<<endl;
            }
        }
        else if(x==2)
        {
            if(!v2.empty())
            {
                tem = v2.front();
                v2.pop();
                cout<<"1 "<<tem.x<<" "<<tem.y<<endl;
            }
            else
            {
                tem = v1.front();
                v1.pop();
                cout<<"3 "<<tem.x<<" "<<tem.y<<endl;
            }
        }
        else
        {
            if(!v1.empty())
            {
                tem = v1.front();
                v1.pop();
                cout<<"2 "<<tem.x<<" "<<tem.y<<endl;
            }
            else
            {
                tem = v2.front();
                v2.pop();
                cout<<"1 "<<tem.x<<" "<<tem.y<<endl;
            }
        }
    }
	return 0;
}

E. Travelling Salesman Problem

题意:n座城市,每座城市有两个属性分别是ai和ci,第i座城市到第j座城市要花费max(aj-ai, ci),求从1出发到其他城市各一次并最后回到1的最小花费。

思路:因为ci是不变的,所以我们要做的就是让所有aj-ai尽可能的不比ci大,那么先尽可能走到ai大的城市,然后再依次往ai小的城市走,这样就是最优的策略,所以按ai的值排个序,再进行判断,需要注意的是起点是1,所以要跑两遍。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 1000000007
#define stree SegTree[root]
#define lson SegTree[root << 1]
#define rson SegTree[root << 1 | 1]
using namespace std;
const int N = 300005;
struct node
{
    LL val, cost, pos;
}a[N];
bool cmp(node x, node y)
{
    if(x.val==y.val) return x.cost<y.cost;
    else return x.val<y.val;
}
int main()
{
    int t, n;
    cin>>n;
    LL ans = 0;
    for(int i = 1;i <= n;i++)
    {
        cin>>a[i].val>>a[i].cost;
        a[i].pos = i;
        ans += a[i].cost;
    }
    sort(a+1, a+1+n, cmp);
    LL tem = a[1].val+a[1].cost, num = 0;
    //printf("tem = %lld\n", tem);
    for(int i = 2;i <= n;i++)
    {
        if(tem>=a[i].val)
        {
            tem = max(tem, a[i].val+a[i].cost);
        }
        else
        {
            ans += a[i].val-tem;
            tem = a[i].val+a[i].cost;
            //printf("1ans = %lld, tem = %lld, a[%d].val = %lld\n", ans,tem,i, a[i].val);
        }
        if(a[i].pos==1)
        {
            num = i;
            break;
        }
    }
    tem = max(tem, a[num].val+a[num].cost);
    if(num)
    {
        for(int i = num+1;i <= n;i++)
        {
            if(tem>=a[i].val)
            {
                tem = max(tem, a[i].val+a[i].cost);
            }
            else
            {
                ans += a[i].val-tem;
                tem = a[i].val+a[i].cost;
                //printf("2ans = %lld, tem = %lld, a[%d].val = %lld\n", ans,tem,i, a[i].val);
            }
        }
    }
    printf("%lld\n", ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值