• Educational Codeforces Round 82 (Rated for Div. 2)【A、B、C、D、E】题解(持续更新)


    涵盖知识点:贪心、dp、模拟、二进制etc.

    比赛链接:

    Educational Codeforces Round 82 (Rated for Div. 2)

    A:Erasing Zeroes

    题意:至少删几个0使得一个0-1串内所有的1都连续。

    题解:记录第一个1的位置和最后一个1的位置输出中间0的个数即可

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int main(){
     5     int t;
     6     cin>>t;
     7     while(t--){
     8         string s;
     9         cin>>s;
    10         int st=-1,ed=-1;
    11         for(int i=0;i<s.length();i++){
    12             if(s[i]=='1'){
    13                 ed=i;
    14                 if(st==-1){
    15                     st=i;
    16                 }
    17             }
    18         }
    19         if(st==-1){
    20             cout<<0<<"
    ";
    21             continue;
    22         }
    23         int res=0;
    24         for(int i=st;i<=ed;i++){
    25             if(s[i]=='0')
    26                 res++;
    27         }
    28         cout<<res<<"
    ";
    29     }
    30     return 0;
    31 }

    B:National Project

    题意:长度为n的道路,每天可以修的长度为1或选择不修,g天好天气和b天坏天气交替出现,要求至少n/2的路是在好天气下修的,问最少几天修完。

    题解:先根据间隔算出遇到n/2天好天气总共需要几天,然后在输出长度和天数的较大值即可(要求路全部修完)。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int main(){
     5     int t;
     6     cin>>t;
     7     while(t--){
     8         ll n,g,b;
     9         ll res=0;
    10         cin>>n>>g>>b;
    11         ll mid=n/2+n%2;
    12         ll gap=mid/g;
    13         if(mid%g==0)gap--;
    14         res+=gap*g;
    15         res+=gap*b;
    16         res+=(mid-gap*g);
    17         cout<<max(res,n)<<"
    ";
    18     }
    19     return 0;
    20 }

    C:Perfect Keyboard

    题意:求a-z一共26个字母排成一行的序列,要求给定的密码串的所有相邻字母在所求序列中也相邻。

    题解:暴力模拟,每添加一个新的字符到序列中时用map记录下标,若序列中已经存在需要新添加的字符时判断是否符合条件,添加字符时判断是否卡死等情况分类讨论。

    AC代码:(写的有点丑,可能有更好的写法或者解法)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 map<char,int> mp;
     5 
     6 int main(){
     7     int t;
     8     cin>>t;
     9     while(t--){
    10         mp.clear();
    11         string s;
    12         cin>>s;
    13         char res[110];
    14         for(int i=0;i<110;i++){
    15             res[i]='#';
    16         }
    17         if(s.length()==1){
    18             cout<<"YES
    ";
    19             for(char i='a';i<='z';i++)
    20                 cout<<i;
    21             cout<<"
    ";
    22             continue;
    23         }
    24         int l=30,r=31;
    25         mp[s[0]]=30;
    26         mp[s[1]]=31;
    27         int idx=31;
    28         res[30]=s[0];
    29         res[31]=s[1];
    30         bool flag=true;
    31         for(int i=2;i<s.length();i++){
    32             if(s[i]==s[i-2]){
    33                 idx=mp[s[i]];
    34                 continue;
    35             }
    36             if(mp[s[i-1]]+1==mp[s[i]]||mp[s[i-1]]-1==mp[s[i]]){
    37                 idx=mp[s[i]];
    38                 continue;
    39             }
    40             if(mp[s[i]]!=0){
    41                 flag=false;
    42                 //cout<<"chongfu
    ";
    43                // cout<<i<<" ";
    44                 //cout<<mp['d']<<" "<<mp['o']<<endl;
    45                 break;
    46             }
    47             if(res[idx+1]=='#'){
    48                 res[++idx]=s[i];
    49                 mp[s[i]]=idx;
    50                 r=idx;
    51             }else if(res[idx-1]=='#'){
    52                 res[--idx]=s[i];
    53                 mp[s[i]]=idx;
    54                 l=idx;
    55             }else{
    56                 flag=false;
    57                 //cout<<"kasi
    ";
    58                 break;
    59             }
    60         }
    61         //cout<<l<<" "<<r<<" ";
    62         //for(int i=l;i<=r;i++){
    63             //cout<<res[i]<<" ";
    64         //}
    65         if(flag){
    66             cout<<"YES
    ";
    67             for(int i=l;i<=r;i++){
    68                 cout<<res[i];
    69             }
    70             for(char i='a';i<='z';i++){
    71                 if(mp[i]==0)
    72                     cout<<i;
    73             }
    74             cout<<"
    ";
    75         }else{
    76             cout<<"NO
    ";
    77         }
    78     }
    79     return 0;
    80 }

    D:Fill The Bag

    题意:给你m个二的倍数,每次操作可以将一个数拆成两半。问你最少几次操作能使n恰好等于其中某些数字的和。

    题解:记录m个数的二进制位总和和n的二进制位,若存在相同位对应位数-1,否则将该位向上移动,每两个贡献合并为高一位的一个贡献。若为负数则向高位借用,记录借用的操作数量即为最终答案。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 ll cnt[70];
     6 int main(){
     7     int t;
     8     cin>>t;
     9     while(t--){
    10         memset(cnt,0,sizeof cnt);
    11         ll sum=0,n,m;
    12         cin>>n>>m;
    13         for(int i=1;i<=m;i++){
    14             int x;
    15             cin>>x;
    16             sum+=x;
    17             int p=0;
    18             while((x>>p)>1)p++;
    19             cnt[p]++;
    20         }
    21         if(sum<n){
    22             cout<<"-1
    ";
    23             continue;
    24         }
    25         int idx=0,ans=0;
    26         while(n||cnt[idx]<0){
    27             cnt[idx]-=(n&1);
    28             if(cnt[idx]<0){
    29                 cnt[idx+1]--;
    30                 ans++;
    31             }else{
    32                 cnt[idx+1]+=(cnt[idx]>>1);
    33             }
    34             n>>=1;
    35             idx++;
    36         }
    37         cout<<ans<<"
    ";
    38     }
    39     return 0;
    40 }

    E:Erase Subsequences

     题意:给字符串s,t。问是否存在s的两个子序列可以构成t(两个子序列不存在公共元素)。

     题解:遍历每一种构成t的可能(即拆解t为t1,t2)。dp[i][j]=k的状态描述为s的前i个和t1的前j个字符匹配时t2匹配的最大值。若存在一组最后dp值大于等于t2的长度,就符合条件。

    思路来源:https://www.bilibili.com/video/av88620060?p=5

    AC代码:(注:通过这题发现了string.length()以及string.size()的返回值为size_type类型,是unsigned类型的,如果前面是负数的话直接拿来比较会出锅)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=410;
     4 int dp[maxn][maxn];
     5 bool check(string s,string t){
     6     int idx=0;
     7     if(idx==s.length())return true;
     8     for(int i=0;i<s.length();i++){
     9         if(s[i]==t[idx])idx++;
    10         if(idx==t.length())return true;
    11     }
    12     return false;
    13 }
    14 bool check(string s,string t1,string t2){
    15     memset(dp,-1,sizeof dp);
    16     dp[0][0]=0;
    17     for(int i=0;i<s.length();i++){
    18         for(int j=0;j<=t1.length();j++){
    19             if(dp[i][j]>=0){
    20                 if(j<t1.length()&&t1[j]==s[i])
    21                     dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]);
    22                 if(dp[i][j]<t2.length()&&t2[dp[i][j]]==s[i])
    23                     dp[i+1][j]=max(dp[i+1][j],dp[i][j]+1);
    24                 dp[i+1][j]=max(dp[i+1][j],dp[i][j]);
    25             }
    26         }
    27     }
    28     int res1= dp[s.length()][t1.length()] ;
    29     int res2=t2.length();
    30     //cout<<res1<<" "<<res2<<endl;
    31     //cout<<dp[s.length()][t1.length()]<<" "<<t2.length()<<endl;
    32     return res1>=res2;
    33    // return dp[s.length()][t1.length()]>=t2.length();
    34 }
    35 void solve(){
    36     string s,t;
    37     cin>>s>>t;
    38     if(check(s,t)){
    39         cout<<"YES
    ";
    40         return;
    41     }
    42     for(int i=0;i<t.length()-1;i++){
    43         string t1="",t2="";
    44         for(int j=0;j<=i;j++)
    45             t1+=t[j];
    46         for(int j=i+1;j<t.length();j++)
    47             t2+=t[j];
    48         bool res=check(s,t1,t2);
    49         if(res){
    50             cout<<"YES
    ";
    51             return;
    52         }
    53     }
    54     cout<<"NO
    ";
    55 }
    56 int main(){
    57     int t;
    58     cin>>t;
    59     while (t--){
    60         solve();
    61     }
    62     return 0;
    63 }

    F:Number of Components

    G:Sum of Prefix Sums

  • 相关阅读:
    如何给发票抬头增加页签
    记录激活SAP SMTP服务过程
    反射
    乱码问题
    使用idea的常用的技巧
    解决double的值相加的问题
    代理模式之静态代理
    foreach的真面目
    记录java的面试的每一个瞬间
    变量的经典
  • 原文地址:https://www.cnblogs.com/charles1999/p/12303221.html
Copyright © 2020-2023  润新知