zoukankan      html  css  js  c++  java
  • Codeforces Round #541题解

    A题

    通过平移线段可以发现其实就是缺少的那一块的大小

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int main(){
        ios::sync_with_stdio(false);
        ll a,b,c,d;
        cin>>a>>b>>c>>d;
        cout<<(a+2)*(b+d+2)-d*(a-c)-a*b-c*d<<endl;
        return 0;
    }
    View Code

    B题

    思维题,因为我们肯定是最优策略,因此当前两个点的最小值和前面的两个最大值的差值相减,但是要和0取max

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N],b[N];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        for(i=2;i<=n+1;i++)
            cin>>a[i]>>b[i];
        ll ans=1;
        a[1]=b[1]=0;
        n++;
        for(i=1;i<=n;i++){
            ans+=max(0,min(a[i],b[i])-max(a[i-1],b[i-1])+1);
            if(a[i-1]==b[i-1])
                ans--;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    C题

    肯定是先递增后递减最好,因为不是这样,最大值无论移到哪里都会变劣

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N],b[N];
    queue<int> q1;
    stack<int> q2;
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i,j,k;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        sort(a+1,a+1+n);
        for(i=1;i<=n;i++){
            if(i&1)
                q1.push(a[i]);
            else
                q2.push(a[i]);
        }
        while(q1.size()){
            cout<<q1.front()<<" ";
            q1.pop();
        }
        while(q2.size()){
            cout<<q2.top()<<" ";
            q2.pop();
        }
        return 0;
    }
    View Code

    D题

    这题显然是比较大小的关系,这容易让我们联想到差分约束建图,虽然差分约束不行,但是建图还是很合理的,我们可以考虑将小点连往大点。但是现在有相同点,这个很好处理,只要考虑并查集,把相同点缩成一个点

    之后就是个拓扑图跑一下最长路,问题是可能有环,也就是冲突情况,这种情况这些点不会进入拓扑排序,因此只要判断一下是否全部都进行了拓扑排序

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e6+10;
    int h[N],ne[N],e[N],idx;
    int ans[N];
    int p[N];
    int in[N];
    int vis[N];
    int flag;
    string s[N];
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    int find(int x){
        if(x!=p[x]){
            p[x]=find(p[x]);
        }
        return p[x];
    }
    void topo(int u){
        queue<int> q;
        ans[u]=1;
        q.push(u);
        while(q.size()){
            int t=q.front();
            q.pop();
            for(int i=h[t];i!=-1;i=ne[i]){
                int j=e[i];
                in[j]--;
                ans[j]=max(ans[j],ans[t]+1);
                if(!in[j]){
                    vis[j]=1;
                    q.push(j);
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i,j;
        for(i=1;i<=n+m;i++){
            p[i]=i;
        }
        memset(h,-1,sizeof h);
        for(i=1;i<=n;i++){
            cin>>s[i];
            s[i]=" "+s[i];
            for(j=1;j<=m;j++){
                if(s[i][j]=='='){
                    int pa=find(i);
                    int pb=find(n+j);
                    if(pa!=pb)
                        p[pa]=pb;
                }
            }
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                int pa=find(i),pb=find(n+j);
                if(s[i][j]=='>'){
                    add(pb,pa);
                    in[pa]++;
                }
                else if(s[i][j]=='<'){
                    add(pa,pb);
                    in[pb]++;
                }
            }
        }
        for(i=1;i<=n+m;i++){
            int pa=find(i);
            if(pa==i&&!in[i]&&!vis[i]){
                vis[i]=1;
                topo(i);
            }
        }
        for(i=1;i<=n+m;i++){
            int pa=find(i);
            if(pa==i&&!vis[i]){
                cout<<"No"<<endl;
                return 0;
            }
        }
        cout<<"Yes"<<endl;
        for(i=1;i<=n;i++){
            int pa=find(i);
            cout<<ans[pa]<<" ";
        }
        cout<<endl;
        for(i=n+1;i<=n+m;i++){
            int pa=find(i);
            cout<<ans[pa]<<" ";
        }
        cout<<endl;
        return 0;
    }
    View Code

    E题

    想的时候没想到,看到题解觉得顺理成章

    主要是观察题目信息,给的信息确实比较明显,因为只考虑单个字符,因此可以使用dp数组记录前i个字符为j的最大子串长度

    因为题目要求的是一个当前pi一个之前的串中单个字符之后再一个pi

    因此我们仔细观察可以发现前缀和后缀的思路。

    之后只要check所有情况取max,注意当当前pi中所有字符相等的时候,要额外考虑,因此其他情况中间都会分割,而这种情况不会,且没有通性。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    ll f[N][30];
    string s;
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i,j;
        memset(f,0,sizeof f);
        for(i=1;i<=n;i++){
            cin>>s;
            int len=(int)s.size();
            s=" "+s;
            int pre=1;
            for(j=2;j<=len;j++){
                if(s[j]==s[1])
                    pre++;
                else
                    break;
            }
            int suf=1;
            for(j=len-1;j>=1;j--){
                if(s[j]==s[len]){
                    suf++;
                }
                else
                    break;
            }
            for(j=0;j<26;j++){
                f[i][j]=(f[i-1][j]>0);
            }
            for(j=1;j<=len;j++){
                int tmp=j;
                while(tmp+1<=len&&s[tmp+1]==s[j])
                    tmp++;
                f[i][s[j]-'a']=max(f[i][s[j]-'a'],1ll*tmp-j+1);
                j=tmp;
            }
            if(pre==len){
                f[i][s[1]-'a']=(f[i-1][s[1]-'a']+1)*len+f[i-1][s[1]-'a'];
            }
            else{
                f[i][s[1]-'a']=max(f[i][s[1]-'a'],1ll*pre+1ll*(f[i-1][s[1]-'a']>0));
                f[i][s[len]-'a']=max(f[i][s[len]-'a'],1ll*suf+1ll*(f[i-1][s[len]-'a']>0));
                if(s[1]==s[len]&&f[i-1][s[1]-'a']){
                    f[i][s[1]-'a']=max(f[i][s[1]-'a'],1ll*pre+suf+1);
                }
            }
        }
        ll ans=0;
        for(i=0;i<26;i++){
            ans=max(ans,f[n][i]);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    F题

    能看的出是并查集的思路,有两种做法,一种是启发式合并,一种是维护头结点之后跑dfs

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    int p[N];
    int n;
    vector<int> num[N];
    int find(int x){
        if(x!=p[x]){
            p[x]=find(p[x]);
        }
        return p[x];
    }
    void dfs(int u){
        int i;
        cout<<u<<" ";
        for(i=0;i<num[u].size();i++){
            int j=num[u][i];
            dfs(j);
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            p[i]=i;
        }
        for(i=1;i<n;i++){
            int a,b;
            cin>>a>>b;
            int pa=find(a);
            int pb=find(b);
            p[pa]=pb;
            num[pb].push_back(pa);
        }
        for(i=1;i<=n;i++){
            if(p[i]==i){
                dfs(i);
                break;
            }
        }
        return 0;
    }
    View Code

    G题

  • 相关阅读:
    【LeetCode-位运算】汉明距离总和
    python类的继承和重写
    单元测试unittest使用说明
    Java学习90
    Java学习89
    Java学习88
    Java学习87
    Java学习86
    Java学习85
    Java学习84
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14170448.html
Copyright © 2011-2022 走看看