A.Codehorses T-shirts

原题链接CF1000A Codehorses T-shirts
题意:
给定个目标尺寸和个现有尺寸,每次只能改变现有尺寸中的一个字符,问变换多少次才可以满足需求
分析
因为最终一定可以将现有的尺寸变换到目标尺寸,用两个标记现有尺寸和目标尺寸,遍历现有尺寸,如果现有尺寸的数量大于目标尺寸,那么多出来的数量一定是需要变到其余少的目标尺寸中去的,多出来的数量和就是答案。
代码

#include<bits/stdc++.h>
using namespace std;
map<string,int> mp1,mp2;
int main() {
    int n;
    cin>>n;
    for(int i=0;i<n;++i) {
        string input;
        cin>>input;
        mp1[input]++;
    }
    for(int i=0;i<n;++i) {
        string input;
        cin>>input;
        mp2[input]++;
    }
    int cnt=0;
    for(auto i=mp1.begin();i!=mp1.end();++i) {
        if(mp2[i->first]<i->second)cnt+=i->second-mp2[i->first];
    }
    cout<<cnt<<endl;
    return 0;
}

B.Alphabetic Removals

原题链接CF999C Alphabetic Removals
题意
给定字符串,通过如下操作从字符串中移除个字符:移除字符串中的字符,如果移除的数量没到个,那么继续这个操作,如果字符串中没有,那么就继续对字符进行这个操作,字符移除完后同理。
分析
模拟。
代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    int len,k;
    string s;
    cin>>len>>k>>s;
    set<char> stc;
    for(auto i:s) stc.insert(i);
    for(auto ch:stc) {
        if(!k)break;
        for(string::iterator i=s.begin();i!=s.end()&&k;++i) {
            if(ch == *i)i=--s.erase(i),k--;
        }
    }
    if(s.length())cout<<s<<endl;
    else cout<<endl;
    return 0;
}

C.Light It Up

原题链接CF1000B Light It Up
题意
有一盏在时刻亮起,同时必须在时刻熄灭的灯,给定一系列初始程序,代表在时刻,会对灯进行一次操作(灯如果是打开状态则关灯,关闭则打开),现在给你一次操作的权力(也可以不操作),问在哪个时刻进行操作,会使亮灯的时间达到最大,这个时间是多少?
分析
动态规划,表示在第时刻没有进行任何操作的亮灯时间,代表在该时刻,插入操作或是已经插入后的亮灯时刻的最大值,因为是已经插入后的操作的最大值,因此累计的亮灯时刻应该和的相反,也就是一个遇到奇数时刻就累计亮灯的时间,一个遇到偶数时刻累计亮灯时间,最后再和不进行任何操作的时间比较一下。
代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100007;
int dp[MAXN][2];
int main() {
    int n,M;
    cin>>n>>M;
    vector<int> ve;
    ve.emplace_back(0);
    for(int i=1;i<=n;++i) {
        int input;
        cin>>input;
        ve.emplace_back(input);
    }
    ve.emplace_back(M);
    dp[0][0]=dp[0][1]=0;
    for(int i=1;i<=n+1;++i) {
        dp[i][0]=dp[i-1][0];
        if(i&1)dp[i][0]+=ve[i]-ve[i-1];
        dp[i][1]=max(dp[i-1][0]+ve[i]-ve[i-1]-1,dp[i-1][1]+((i&1)?0:ve[i]-ve[i-1]));
    }
    cout<<max(dp[n+1][1],dp[n+1][0])<<endl;
    // system("pause");
    return 0;
}

D.Convert to Ones

原题链接CF997A Convert to Ones
题意
有一个长度为且只含的字符串,同时有两种操作
(1)将一段字符(字串或它本身)反转,同时需要花费的代价
(2)将一段字符(字串或它本身)中的变为变为(即异或),同时需要花费的代价
那么把变为只含的字符串最少需要花费多少?
分析
先分析一下两个操作:
(1)其实每进行一次反转操作,都可以把两段含有连续的子段合到一起,那么也就是说我们可以最多可以进行的反转操作的次数就是:连续的子段的个数
(2)为了达成最少花费,每次异或操作都必须在上操作,如果我们操作的子段中有1,那么必定会有另一个含子段的异或操作会覆盖到这个,也就是说,任何对的操作都是无用功,不需要考虑。

接下来从初始状态开始分析:
如果我们不进行反转操作,那么需要花费的最小代价就是
如果我们进行一次反转操作,那么需要花费的最小代价就是
如果进行n次操作,最小代价就是,同时
当我们进行次反转操作后,最小代价是

接下来分类讨论的情况:
时,
也就是
时,同理可得
那么答案其实也就是
代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n;
    long long x,y;
    cin>>n>>x>>y;
    string s;
    cin>>s;
    int cnt=0;
    for(int i=0;i<n;++i) {
        int flag=1;
        while(s[i]=='0') {
            cnt+=flag;
            flag=0;
            i++;
        }
    }
    if(cnt)cout<<(long long)(min((cnt-1)*x+y,cnt*y))<<endl;
    else cout<<0<<endl;
    return 0;
}

E.Covered Points Count

原题链接CF1000C Covered Points Count
题意
个线段的起点,问被覆盖次的点共有几个,其中
分析
差分。
代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 500007;
long long cnt[MAXN];
inline long long read()
{
    char ch=getchar();long long ans=0,flag=1;
    while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){ans=ans*10+ch-'0';ch=getchar();}
    return ans*flag;
}
map<long long,long long> mp;
int main() {
    int n=read();
    for(int i=0;i<n;++i) {
        long long l=read(),r=read();
        ++mp[l];
        --mp[r+1];
    }
    long long mark=0,fro=0;
    for(auto i=mp.begin();i!=mp.end();++i) {
        cnt[mark]+=i->first-fro;
        fro=i->first;
        mark+=i->second;
    }
    for(int i=1;i<=n;++i) cout<<cnt[i]<<" ";
    return 0;
}