• Codeforces Round #568题解


    第一次遇到有9题的div2。。。

    A题

    排序后,伸展两边

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    ll a[4];
    int main(){
        ios::sync_with_stdio(false);
        ll d;
        cin>>a[1]>>a[2]>>a[3]>>d;
        sort(a+1,a+4);
        ll ans=0;
        ans+=max(0ll,d-a[2]+a[1]);
        ans+=max(0ll,d-a[3]+a[2]);
        cout<<ans<<endl;
        return 0;
    }
    View Code

    B题

    写了个臭暴力,因为输入的是按序的,所以一位一位匹配,当不同了,看看B有没有机会变成和当前的一样的,其实就是越过中间相等的部分

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            string a,b;
            cin>>a>>b;
            int i,j;
            int flag=0;
            for(i=0,j=0;i<a.size()&&j<b.size();){
                if(a[i]==b[j]){
                    i++,j++;
                }
                else{
                    int tmp=j;
                    while(j<b.size()&&b[j]==b[j-1]){
                        j++;
                    }
                    if(tmp==j){
                        flag=1;
                        break;
                    }
                }
            }
            if(flag){
                cout<<"NO"<<endl;
            }
            else{
                if(i!=a.size()){
                    flag=1;
                }
                j--;
                for(i=j+1;i<b.size();i++){
                    if(b[i]!=b[j]){
                        flag=1;
                        break;
                    }
                }
                if(flag){
                    cout<<"NO"<<endl;
                }
                else{
                    cout<<"YES"<<endl;
                }
            }
        }
        return 0;
    }
    View Code

    C题

    分为两个version,直接讲hard,这题就是当前数必取,之后能在M范围内前面的数取的越多越好

    不难想到使用优先队列,但是过了这个数后,这个数不一定要取,因此维护一个对顶堆,先让当前满足条件,然后把数加回来

    有个很重要的点是,权值不大于100,因此每次操作不大于100次

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int a[N];
    ll sum[N];
    int ans[N];
    priority_queue<int> q;
    priority_queue<int,vector<int>,greater<int>> p;
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];
        }
        ll tot=0;
        for(i=1;i<=n;i++){
            p.push(a[i]);
            while(tot+a[i]>m){
                int tmp=q.top();
                q.pop();
                p.push(tmp);
                tot-=tmp;
            }
            ans[i]=i-q.size()-1;
            while(p.size()){
                int tmp=p.top();
                if(tot+tmp<=m){
                    tot+=tmp;
                    p.pop();
                    q.push(tmp);
                }
                else{
                    break;
                }
            }
            int tmp=a[i];
        }
        for(i=1;i<=n;i++){
            cout<<ans[i]<<" ";
        }
        cout<<endl;
        return 0;
    }
    View Code

    D题

    先排序

    维护一个map,因为权值相等,就是相当于要不只有一个树,要不只有一种差值,因此我们枚举哪个差值要删除,然后看有没有合适情况

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int a[N];
    int b[N];
    map<ll,int> m1;
    map<ll,int> pos;
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
            pos[a[i]]=i;
        }
        sort(a+1,a+1+n);
        for(i=2;i<=n;i++){
            b[i]=a[i]-a[i-1];
        }
        for(i=2;i<=n;i++){
            m1[b[i]]++;
        }
        int flag=0;
        for(i=1;i<=n;i++){
            if(i==1){
                int tmp=a[2]-a[1];
                m1[tmp]--;
                if(m1[tmp]==0){
                    m1.erase(tmp);
                }
                if(m1.size()==0||m1.size()==1){
                    flag=1;
                    cout<<pos[a[1]]<<endl;
                    break;
                }
                m1[tmp]++;
            }
            else if(i==n){
                int tmp=a[n]-a[n-1];
                m1[tmp]--;
                if(m1[tmp]==0){
                    m1.erase(tmp);
                }
                if(m1.size()==0||m1.size()==1){
                    flag=1;
                    cout<<pos[a[n]]<<endl;
                    break;
                }
                m1[tmp]++;
            }
            else{
                int f1=a[i]-a[i-1];
                int f2=a[i+1]-a[i];
                int f3=a[i+1]-a[i-1];
                m1[f1]--;
                m1[f2]--;
                m1[f3]++;
                if(m1[f1]==0){
                    m1.erase(f1);
                }
                if(m1[f2]==0){
                    m1.erase(f2);
                }
                if(m1.size()==0||m1.size()==1){
                    flag=1;
                    cout<<pos[a[i]]<<endl;
                    break;
                }
                m1[f1]++;
                m1[f2]++;
                m1[f3]--;
                if(m1[f3]==0){
                    m1.erase(f3);
                }
            }
        }
        if(!flag){
            cout<<-1<<endl;
        }
        return 0;
    }
    View Code

    E题

    暴力题

    首先把每个字母所有的位置存下来,然后从小到大枚举,如果没有,那就取最后一个字母的随便一个位置,因为这个位置一定是不被覆盖了

    如果一个,那就这个位置,如果有多个,那就枚举这个字母的位置看是否符合情况

    最后check一遍看是否和原来一样

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    const int mod=1e9+7;
    struct node{
        int x,y;
    };
    struct Node{
        int a,b,c,d;
    };
    vector<node> pos[2020];
    vector<Node> ans;
    int a[2020][2020];
    int b[2020][2020];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            ans.clear();
            int n,m;
            cin>>n>>m;
            int i,j,k;
            for(i=0;i<=26;i++){
                pos[i].clear();
            }
            for(i=1;i<=n;i++){
                for(j=1;j<=m;j++){
                    a[i][j]=0;
                    b[i][j]=0;
                }
            }
            int mx=0;
            for(i=1;i<=n;i++){
                string s;
                cin>>s;
                s=" "+s;
                for(j=1;j<=m;j++){
                    if(s[j]=='.')
                        continue;
                    a[i][j]=s[j]-'a'+1;
                    pos[a[i][j]].push_back({i,j});
                    mx=max(mx,a[i][j]);
                }
            }
            int flag=0;
            for(i=1;i<=mx;i++){
                if(pos[i].size()==0){
                    int x=pos[mx][0].x,y=pos[mx][0].y;
                    ans.push_back({x,y,x,y});
                }
                else if(pos[i].size()==1){
                    int x=pos[i][0].x,y=pos[i][0].y;
                    ans.push_back({x,y,x,y});
                }
                else{
                    int x1=pos[i][0].x,y1=pos[i][0].y;
                    int x2=pos[i][1].x,y2=pos[i][1].y;
                    if(x1!=x2&&y1!=y2){
                        flag=1;
                        break;
                    }
                    if(x1==x2){
                        for(auto x:pos[i]){
                            if(x.x!=x1){
                                flag=1;
                                break;
                            }
                        }
                    }
                    if(y1==y2){
                        for(auto x:pos[i]){
                            if(x.y!=y1){
                                flag=1;
                                break;
                            }
                        }
                    }
                    ans.push_back({x1,y1,pos[i][pos[i].size()-1].x,pos[i][pos[i].size()-1].y});
                }
            }
            if(flag){
                cout<<"NO"<<endl;
                continue;
            }
            for(i=0;i<mx;i++){
                for(j=ans[i].a;j<=ans[i].c;j++){
                    for(k=ans[i].b;k<=ans[i].d;k++){
                        b[j][k]=i+1;
                    }
                }
            }
            for(i=1;i<=n;i++){
                for(j=1;j<=m;j++){
                    if(a[i][j]!=b[i][j]){
                        flag=1;
                        break;
                    }
                }
                if(flag)
                    break;
            }
            if(flag){
                cout<<"NO"<<endl;
            }
            else{
                cout<<"YES"<<endl;
                cout<<mx<<endl;
                for(i=0;i<mx;i++){
                    cout<<ans[i].a<<" "<<ans[i].b<<" "<<ans[i].c<<" "<<ans[i].d<<endl;
                }
            }
        }
        return 0;
    }
    View Code

    F题

    一道状压,感觉比较好想,因为时限给了4s。

    我们看到有9种,不难想到可以状压出状态,首先n和m的关系不能直接算,因为数据太大

    因此需要一个媒介联通他们,这样这个不大于1024的数就起到了作用,我们发现如果可以枚举1024种情况,再分别维护n,m,复杂度在1e8左右

    因此想到,1024种情况,分别计算他能够符合多少人,然后我们枚举面包,因为只能取两个面包,所以需要维护选这个面包能到达的状态的花费最小值和id

    这样我们就可以枚举1024种情况计算选两个面包的答案

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    const int mod=1e9+7;
    ll f[N];
    ll d[N];
    ll cost[N],st[N],id[N];
    vector<int> res;
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        int i,j,k;
        cin>>n>>m;
        for(i=1;i<=n;i++){
            int x;
            cin>>x;
            for(j=1;j<=x;j++){
                int tmp;
                cin>>tmp;
                f[i]|=(1<<(tmp-1));
            }
        }
        int ans=0;
        int tot=0x3f3f3f3f;
        memset(cost,0x3f,sizeof cost);
        for(i=0;i<1<<10;i++){
            for(j=1;j<=n;j++){
                if((f[j]&i)==f[j]){
                    d[i]++;
                }
            }
        }
        res.push_back(1);
        res.push_back(2);
        for(i=1;i<=m;i++){
            ll x,c;
            cin>>x>>c;
            int tmp=0;
            for(j=1;j<=c;j++){
                int y;
                cin>>y;
                tmp|=(1<<(y-1));
            }
            for(j=0;j<1<<10;j++){
                if(st[j]){
                    if(ans<d[j|tmp]){
                        ans=d[j|tmp];
                        tot=cost[j]+x;
                        res.clear();
                        res.push_back(id[j]);
                        res.push_back(i);
                    }
                    else if(ans==d[j|tmp]&&tot>cost[j]+x){
                        tot=cost[j]+x;
                        res.clear();
                        res.push_back(id[j]);
                        res.push_back(i);
                    }
                }
            }
            st[tmp]=1;
            if(cost[tmp]>x){
                cost[tmp]=x;
                id[tmp]=i;
            }
        }
        cout<<res[0]<<" "<<res[1]<<endl;
        return 0;
    }
    View Code

    G1题

    状压dp,根据题目范围,设计状态为选择i,最后的种类是j,这样往大了更新即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int a[N],b[N];
    ll f[N][4];
    int main(){
        ios::sync_with_stdio(false);
        int n,T;
        cin>>n>>T;
        int i,j,k;
        for(i=1;i<=n;i++){
            cin>>a[i]>>b[i];
        }
        f[0][0]=1;
        for(i=0;i<(1<<n);i++){
            for(j=0;j<=3;j++){
                for(k=1;k<=n;k++){
                    if(i>>(k-1)&1)
                        continue;
                    if(b[k]==j)
                        continue;
                    f[i|(1<<k-1)][b[k]]=(f[i|(1<<k-1)][b[k]]+f[i][j])%mod;
                }
            }
        }
        ll ans=0;
        for(i=1;i<(1<<n);i++){
            int cnt=0;
            for(j=1;j<=n;j++){
                if(i>>(j-1)&1){
                    cnt+=a[j];
                }
            }
            if(cnt==T){
                ans=(ans+f[i][1]+f[i][2]+f[i][3])%mod;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    G2题

    待补,没啥思路。

    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    JavaScript笔试必备语句
    JQuery获取元素的方法总结
    JavaScript易错知识点整理
    程序员都讨厌开会?
    JS操作select下拉框动态变动(创建/删除/获取)
    用 jQuery.ajaxSetup 实现对请求和响应数据的过滤
    HTML5 学习笔记(一)——HTML5概要与新增标签
    json返回数据库的时间格式为/Date(1477294037000)/,怎样在前台进行格式化转换
    Hive 12、Hive优化
    Hive 11、Hive嵌入Python
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14617435.html
Copyright © 2020-2023  润新知