Codeforces Round #738 (Div. 2)

前四个题就A题难想一点,别的读懂题就可以写出来。
结果这题卡我一个多小时

A. Mocha and Math

在这里插入图片描述

题意:给你一个序列,你可以对称的把区间里的 a i a_i ai替换成 a i + l a_{i+l} ai+l & a r − i a_{r-i} ari,如上图。问你操作若干次之后序列中的最小值。
思路:首先了解&的性质, A A A & B < = m i n ( A , B ) B<=min(A,B) B<=min(A,B),所以随着&操作的增加,值肯定是不断减少的,对于序列的某一个元素来说,它可以选择无数个区间使得 a i a_i ai被替换成 a 1 a_1 a1& a 2 a_2 a2& a 3 a_3 a3& . . . . . ..... .....& a n a_n an,根据性质,此时的 a i a_i ai已经达到了潜力上的最小值,此时无论再与谁&运算也不会更小了,所以我们干脆把所有的数都&一遍,最小的那个元素的贡献一定在其中,因为本身&也有类似取最小值的性质。

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int mod = 1e9+7;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 1e5+10;
int a[N];
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       int n;
       cin>>n;
       for(int i=1;i<=n;i++) cin>>a[i];
       LL res=a[1];
       for(int i=1;i<=n;i++)
       {
           res=res&a[i];
       }
       cout<<res<<endl;
   }
}
 

B - Mocha and Red and Blue

直接找到第一个非 ‘?’ ,遍历其左右。
显然只要保证与之前存在的字符不同,就可以贪心的得到最优解。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        string st;
        cin>>st;
        int k=-1;
        int flag=0;
        for(int i=0;i<n;i++)
        {
            if(st[i]!='?'&&k==-1)
            {
                k=i;
            }
            if(st[i]=='?') flag++;
        }
        if(flag==n)
        {
            for(int i=1;i<=n;i++)
            {
                if(i%2) cout<<'B';
                else cout<<'R';
            }
            puts("");
            continue;
        }
        if(k==-1) {cout<<st<<endl;continue;}
        else
        {
            for(int i=k;i>=1;i--)
            {
                if(st[i]=='R'&&st[i-1]=='?') st[i-1]='B';
                else if(st[i]=='B'&&st[i-1]=='?') st[i-1]='R';
            }
            for(int i=k;i<=n-2;i++)
            {
                if(st[i]=='R'&&st[i+1]=='?') st[i+1]='B';
                else if(st[i]=='B'&&st[i+1]=='?') st[i+1]='R';
            }
        }
        cout<<st<<endl;
    }
}

C - Mocha and Hiking

读懂题就行,判断一下最后一辆车能否到达终点。

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int mod = 1e9+7;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 1e5+10;
int a[N];
int main()
{
   int t;
   cin>>t;
   while(t--)
   {
       int n;
       cin>>n;
       for(int i=1;i<=n;i++) cin>>a[i];
       if(a[n]==0)
       {
           for(int i=1;i<=n+1;i++) cout<<i<<' ';
           puts("");
       }
       else
       {
           int k=-1;
           for(int i=n;i>=1;i--)
           {
               if(!a[i])
               {
                   k=i;
                   break;
               }
           }
           if(k==-1)
           {
               cout<<n+1<<" ";
               for(int i=1;i<=n;i++) cout<<i<<" ";
               cout<<endl;
           }
           else
           {
               for(int i=1;i<=k;i++) cout<<i<<' ';
               cout<<n+1<<' ';
               for(int i=k+1;i<=n;i++) cout<<i<<' ';
               cout<<endl;
           }
       }
   }
}
 

D1 - Mocha and Diana (Easy Version)

不 形 成 环 = 在 一 个 连 通 块 之 中 的 点 对 不 再 建 边 不形成环=在一个连通块之中的点对不再建边 =

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
const int mod = 1e9+7;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 1e5+10;
int p1[N];
int p2[N];
PII ans[N];
int find1(int x)
{
    if(x==p1[x]) return x;
    else return p1[x]=find1(p1[x]);
}
int find2(int x)
{
    if(x==p2[x]) return x;
    else return p2[x]=find2(p2[x]);
}
void merge(int x,int y)
{
    int px=find1(x);
    int py=find1(y);
    p1[px]=py;
    px=find2(x);
    py=find2(y);
    p2[px]=py;
}
int main()
{
   int n,m1,m2;
   cin>>n>>m1>>m2;
   int a,b;
   for(int i=1;i<=n;i++) p1[i]=i,p2[i]=i;
   
   while(m1--)
   {
       cin>>a>>b;
       if(find1(a)!=find1(b))
       {
           p1[find1(a)]=find1(b);
       }
   }
   while(m2--)
   {
       cin>>a>>b;
       if(find2(a)!=find2(b))
       {
           p2[find2(a)]=find2(b);
       }
   }
   int ct=0;
   for(int i=1;i<=n;i++)
   {
       for(int j=i+1;j<=n;j++)
       {
           if(find1(i)!=find1(j)&&find2(i)!=find2(j))
           {
               ans[++ct]={i,j};
               merge(i,j);
           }
       }
   }
   cout<<ct<<endl;
   for(int i=1;i<=ct;i++) cout<<ans[i].x<<' '<<ans[i].y<<endl;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值