Educational Codeforces Round 82 (Rated for Div. 2) 部分题解

传送门

A题: 将夹杂在1中的0给删除即可。

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include<bits/stdc++.h>
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=2e5+5;
 
 
int main()
{
    string s;
    int T;
    scanf("%d",&T);
    while(T--){
        cin>>s;
        int j=0,k=0,num=0;
        int n=s.size();
        for(int i=0;i<n;i++){
            if(s[i]=='1'){j=i;break;}
        }
        for(int i=n-1;i>=0;i--){
            if(s[i]=='1'){k=i;break;}
        }
        for(int i=j;i<k;i++){
            if(s[i]=='0'){num++;}
        }
        printf("%d\n",num);
    }
    return 0;
}

B题: 答案具有单调性,直接二分枚举最少天数

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include<bits/stdc++.h>
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=2e5+5;
 
bool check(ll mid,ll g,ll b,ll n)
{
    n=(n+1)/2;
    ll m=g+b;
    if((mid/m*g+min(mid%m,g))>=n){return true;}
    else{return false;}
}
int main()
{
    int T;
    ll n,g,b;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld",&n,&g,&b);
        ll l=n,r=1e18,ans;
        while(l<=r){
            ll mid=(l+r)>>1;
            if(check(mid,g,b,n)){
                ans=mid,r=mid-1;
            }
            else{
                l=mid+1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

C题: dfs+建边。
1.相邻字符建立一条边,再判断一个字符是否最多相邻两个字符。
2.对 度数 < 2 && 未访问字符 进行dfs。(为啥对度 < 2 的进行搜索呢? 你想一下,情况1:孤立的一个字符;情况2:仅连接一个字符。我们假设答案YES的话,那么最终的排序必然是一条链,我们对孤立字符不考虑的话,那可以对链两端( 度1 )开始dfs出该链,若你对度2的考虑你的链将不正确,无法准确排出另一方向的链)
3.若存在为访问的点(度都为2构成环去了),直接输出NO

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include <bits/stdc++.h>
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e5+5;

string p;
char s[205];
bool vis[30],ans[30][30];
int indx[30];

void dfs(int now)
{
    if(vis[now]){return ;}
    vis[now]=true;p+=now+'a';
    for(int i=0;i<26;i++){
        if(!vis[i]&&ans[now][i]){
            dfs(i);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        mem(ans,false);mem(vis,false);mem(indx,0);p="";
        scanf("%s",s+1);
        for(int i=2;s[i];i++){
            int a=s[i-1]-'a';
            int b=s[i]-'a';
            ans[a][b]=ans[b][a]=true;
        }
        for(int i=0;i<26;i++){
            ans[i][i]=false;
            for(int j=0;j<26;j++){
                if(ans[i][j]){indx[i]++;}
            }
        }
        bool flag=false;
        for(int i=0;i<26;i++){
            if(indx[i]>2){printf("NO\n");flag=true;break;}
        }
        if(flag){continue;}
        for(int i=0;i<26;i++){
            if(!vis[i]&&indx[i]<2){dfs(i);}
        }
        for(int i=0;i<26;i++){
            if(!vis[i]){printf("NO\n");flag=true;break;}
        }
        if(flag){continue;}
        printf("YES\n");cout<<p<<endl;
    }
    return 0;
}

D题: 直接暴力处理即可。
1.可以直接判断无法构成的情况。
2.预先处理出二进制状态下每位的个数 bit[] ,再将n转化为二进制形式从低位开始处理,如果该位bit[]>0,说明可以用去组合;反之,向高位寻找第一个bit[]>0,然后用它去拆分直至拆分到当前位。
3.处理完当前位后,需进行合并到高位,bit [i+1] += bit [i] / 2;

#define first f
#define second s
#define ll long long
#define mp make_pair
#define pb push_back
#define pf push_front
#define lb lower_bound
#define ub upper_bound
#include <bits/stdc++.h>
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e5+5;
 
int bit[66];
 
int main()
{
    int T,m,ant,cnt;
    ll sum,n;
    scanf("%d",&T);
    while(T--){
        mem(bit,0);cnt=0;sum=0;
        scanf("%lld%d",&n,&m);
        for(int i=1,j;i<=m;i++){
            scanf("%d",&j);sum+=j;
            for(int k=0;k<30;k++){
                if((1<<k)==j){bit[k]++;}
            }
        }
        if(sum<n){printf("-1\n");continue;}
        for(int i=0;i<60;i++){
            if(n&(1ll<<i)){
                for(int j=i;j<60;j++){
                    if(bit[j]){
                        bit[j]--;
                        for(int k=i;k<j;k++){
                            bit[k]++;
                        }
                        break;
                    }
                    cnt++;
                }
            }
            bit[i+1]+=bit[i]/2;
        }
        printf("%d\n",cnt);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值