Codeforces Round #637 (Div. 2) - Thanks, Ivan Belonogov! 题解

在这里插入图片描述

写题解防hack

A. Nastya and Rice

水题略

B. Nastya and Door

队列维护一下就行

C. Nastya and Strange Generator

弄两组指针,分别指向前面和后面,用multiset维护最大值即可

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-23-22.58.02
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

int a[maxn];
int pos[maxn];
int pre[maxn];
int nex[maxn];

int main(){
    int t=rd;
    while(t--){
        multiset<int>S;
        int n=rd;
        rep(i,1,n){
            a[i]=rd;
            pos[a[i]]=i;
            pre[i]=i-1;
            nex[i]=i+1;
            S.insert(1);
        }
        bool cant=0;
        rep(i,1,n){
            int p=pos[i];
            auto it=S.end();
            it--;
            int mx=*it;
            if(p-pre[p]!=mx){
                cant=1;break;
            }
            int L=pre[p],R=nex[p];
            it=S.find(p-pre[p]);
            S.erase(it);
            pre[R]=L;nex[L]=R;
            if(R<=n){
                S.insert(R-L);
            }
        }
        if(cant)puts("No");
        else puts("Yes");
    }
    return 0;
}

/*_________________________________________________________end*/

D. Nastya and Scoreboard

用dp[i][j]维护好 [ i , n ] [i,n] j j 个火柴是否可行,最后从前往后贪心

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-23-23.15.25
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=2e3+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

char* tp[10]={
    "1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011"
};

char x[maxn][9];
int nd[maxn][10];
bool dp[maxn][maxn];

int main(){
    int n=rd,K=rd;
    rep(i,1,n){
        scanf("%s",x[i]);
    }
    rep(i,1,n){
        rep(j,0,9){
            rep(k,0,6){
                if(x[i][k]==tp[j][k])continue;
                if(x[i][k]=='0')nd[i][j]++;
                else nd[i][j]+=1e7;
            }
        }
    }
    dp[n+1][0]=1;
    per(i,n,1){
        rep(now,0,9){
            int need=nd[i][now];
            if(need>1e5)continue;
            rep(j,need,K){
                dp[i][j]|=dp[i+1][j-need];
            }
        }
    }
    int cnt=0;
    bool yes=0;
    rep(i,1,n){
        per(now,9,0){
            int need=nd[i][now];
            if(need>1e5)continue;
            if(dp[i+1][K-cnt-need]){
                yes=1;
                putchar('0'+now);
                cnt+=need;
                break;
            }
        }
        if(!yes)break;
    }
    if(!yes)puts("-1");

    return 0;
}

/*_________________________________________________________end*/

E. Nastya and Unexpected Guest

将点按照路灯时间拆开,做一遍迪杰斯特拉。过程中时刻维护ans即可。

剪枝: 当前点权大于ans时结束

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-23-23.33.46
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e4+3;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int len,n;
int p[maxn];
int dis[maxn][1002];
bool vis[maxn][1002];
int a,b;

struct node{
    int d,p,sta;
    bool operator<(const node &A)const{
        return d>A.d;
    }
};

int bfs(){
    mmm(dis,0x3f);
    priority_queue<node>Q;
    if(p[1]>a)return -1;
    else if(p[1]<a){
        dis[1][p[1]]=p[1];
        Q.push({p[1],1,p[1] });
    }
    else{
        dis[1][0]=a+b;
        Q.push({a+b,1,0 });
    }

    int ans=inf;
    while(!Q.empty()){
        node P=Q.top();Q.pop();
        if(vis[P.p][P.sta])continue;
        vis[P.p][P.sta]=1;

        if(P.sta==0&&len-p[P.p]<=a){
            ans=min(ans,dis[P.p][P.sta]+len-p[P.p]);
            continue;
        }
        if(dis[P.p][P.sta]>=ans)continue;

        if(P.p>1){
            int sub=p[P.p]-p[P.p-1];
            if(P.sta+sub<a){
                if(dis[P.p-1][P.sta+sub]>dis[P.p][P.sta]+sub){
                    dis[P.p-1][P.sta+sub]=dis[P.p][P.sta]+sub;
                    Q.push({dis[P.p-1][P.sta+sub],P.p-1,P.sta+sub});
                }
            }
            else if(P.sta+sub==a){
                if(dis[P.p-1][0]>dis[P.p][P.sta]+sub+b){
                    dis[P.p-1][0]=dis[P.p][P.sta]+sub+b;
                    Q.push({dis[P.p-1][0],P.p-1,0});
                }
            }
        }
        if(P.p<n){
            int sub=p[P.p+1]-p[P.p];
            if(P.sta+sub<a){
                if(dis[P.p+1][P.sta+sub]>dis[P.p][P.sta]+sub){
                    dis[P.p+1][P.sta+sub]=dis[P.p][P.sta]+sub;
                    Q.push({dis[P.p+1][P.sta+sub],P.p+1,P.sta+sub});
                }
            }
            else if(P.sta+sub==a){
                if(dis[P.p+1][0]>dis[P.p][P.sta]+sub+b){
                    dis[P.p+1][0]=dis[P.p][P.sta]+sub+b;
                    Q.push({dis[P.p+1][0],P.p+1,0});
                }
            }
        }
    }
    if(ans==inf)return -1;
    return ans;
}

int main(){
    len=rd,n=rd;
    rep(i,1,n){
        p[i]=rd;
    }
    sort(p+1,p+1+n);
    a=rd,b=rd;
    if(len<=b){
        printf("%d\n",len);
        return 0;
    }
    printf("%d\n",bfs());


    return 0;
}

/*_________________________________________________________end*/

发布了790 篇原创文章 · 获赞 348 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/105722142
今日推荐