Codeforces Round 933 (Div. 3)

Codeforces Round 933 (Div. 3)

A

A - Rudolf and the Ticket

暴力

查看代码
void solve() {
    int n,m,k;
    cin>>n>>m>>k;
    vector<int>b(n),c(m);
    for(int i=0;i<n;++i)cin>>b[i];
    for(int i=0;i<m;++i)cin>>c[i];
    int ans=0;
    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j){
            if(b[i]+c[j]<=k)ans++;
        }
    }
    cout<<ans<<'\n';
}

 

B

B - Rudolf and 121

思路:对于a[1]的操作一定在i为2,同理a[1]为0后,对a[2]的操作一定在i为3,....,最终看最后两个数是否为0即可

查看代码
 void solve() {
    int n;
    cin>>n;
    vector<int>ve(n);
    for(int i=0;i<n;++i)cin>>ve[i];
    for(int i=1;i<n-1;++i){
        int c=ve[i-1];
        ve[i-1]-=c,ve[i]-=2*c,ve[i+1]-=c;
        if(ve[i]<0||ve[i+1]<0){
            cout<<"NO\n";
            return ;
        }
    }
    if(ve[n-1]>0||ve[n-2]>0)cout<<"NO\n";
    else
    cout<<"YES\n";
}

 

C

C - Rudolf and the Ugly String

思路:三种情况,出现map、pie、mapie时操作一次即可

查看代码
 void solve() {
    int n;
    cin>>n;
    string s;
    cin>>s;
    int ans=0;
    for(int i=0;i+2<n;++i){
        if(i+4<n&&s[i]=='m'&&s[i+1]=='a'&&s[i+2]=='p'&&s[i+3]=='i'&&s[i+4]=='e'){
            ans++;
            i+=4;
        }else if(s[i]=='m'&&s[i+1]=='a'&&s[i+2]=='p')ans++,i+=2;
        else if(s[i]=='p'&&s[i+1]=='i'&&s[i+2]=='e')ans++,i+=2;
    }
    cout<<ans<<'\n';
}

 

D

D - Rudolf and the Ball Game

思路:用set维护下当前可能在的地方

查看代码
 void solve() {
    int n,m,x;
    cin>>n>>m>>x;
    set<int>se;
    se.insert(x);
    set<int>t;
    for(int i=0;i<m;++i){
        int d;
        char c;
        cin>>d>>c;
        for(auto v:se){
            if(c=='0') {
                int y=(v+d)%n;
                if(y==0)y=n;
                t.insert(y);
            }else if(c=='1'){
                int y=(v-d+n)%n;
                if(y==0)y=n;
                t.insert(y);
            }else{
                int y=(v+d)%n;
                if(y==0)y=n;
                t.insert(y);
                y=(v-d+n)%n;
                if(y==0)y=n;
                t.insert(y);
            }
        }
        se=t;
        t.clear();
    }
    cout<<se.size()<<'\n';
    for(auto v:se)cout<<v<<' ';
    cout<<'\n';
}

 

E

E - Rudolf and k Bridges

思路:

先求出每行最少需要的支架个数,维护最少的连续k行

对于一行,已知支架之间的最大距离,若当前位置建立支架,用优先队列维护花费最少的上一个可行支架(距离可行),更新在当前位置的最少花费

查看代码
 void solve() {
    int n,m,k,d;
    cin>>n>>m>>k>>d;
    vector<vector<int>>ve(n+1,vector<int>(m+1));
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)cin>>ve[i][j];
    vector<int>sum(n+1);
    for(int i=1;i<=n;++i){
        priority_queue<PII,vector<PII>,greater<PII>>q;
        q.push({1,1});
        for(int j=2;j<=m;++j){
            while(q.top().second<j-d-1){
                q.pop();
            }
            if(j==m)sum[i]=q.top().first+ve[i][j]+1;
            else q.push({q.top().first+ve[i][j]+1,j});
        }
    }
    int ans=LLONG_MAX,t=0;
    for(int i=1;i<=n;++i){
//        cout<<sum[i]<<'\n';
        t+=sum[i];
        if(i>=k){
            ans=min(ans,t);
            t-=sum[i-k+1];
        }
    }
    cout<<ans<<'\n';
}

 

F

F - Rudolf and Imbalance

思路:求a最小的最大差值

由于最多插入一个,若a存在多个最大差值,答案即为最大差值

若只存在一个最大差值r-l,即在(l,r)之间插入,插入后的差值与原第二大差值比较即可

考虑插入的数应该趋近于中间,为mid=l+r>>1

而后枚举d,f应该趋近于mid-d,二分出趋近于mid-d的f,将求出的数与l和r取差值,维护最小差值即可

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e6+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};


void solve() {
    int n,m,k;
    cin>>n>>m>>k;
    vector<int>a(n),d(m),f(k),dd;
    for(int i=0;i<n;++i){
        cin>>a[i];
        if(i){
            dd.push_back(a[i]-a[i-1]);
        }
    }
    for(int i=0;i<m;++i)cin>>d[i];
    for(int i=0;i<k;++i)cin>>f[i];
    sort(f.begin(),f.end());
    std::sort(dd.begin(), dd.end(),greater<int>());
    if(n>2&&dd[0]==dd[1])cout<<dd[0]<<'\n';
    else{
        int l=0,r=0;
        for(int i=1;i<n;++i){
            if(a[i]-a[i-1]==dd[0]){
                l=a[i-1],r=a[i];
                break;
            }
        }
        int mid=(l+r)/2;
        int mi=dd[0];
        for(int i=0;i<m;++i){
            auto pr= std::lower_bound(f.begin(), f.end(),mid-d[i]);
            auto pl=f.end();
            if(pr!=f.begin())pl= prev(pr);
            if(pr!=f.end()){
                int x=d[i]+*pr;
                if(x>l&&x<r){
                    mi=min(mi,max(x-l,r-x));
                }
            }
            if(pl!=f.end()){
                int x=d[i]+*pl;
                if(x>l&&x<r){
                    mi=min(mi,max(x-l,r-x));
                }
            }
        }
        int ans;
        if(n==2)ans=mi;
        else ans=max(mi,dd[1]);
        cout<<ans<<'\n';
    }

}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
//    init();
    while(t--){
        solve();
    }
    return 0;
}

 

G

G - Rudolf and Subway

思路:一段连续的颜色相同的边形成一条路线,要求s到t的路线个数,可以考虑把每个颜色当作一个节点,边上的端点与这条边的颜色建无向边,相当于如果一条长度为n的路线端点想相互到达只需要花2步,如此一来,可以bfs求s到t的最短路,最后步数除2即为s到t的最少路线个数

查看代码
 #include<bits/stdc++.h>
using namespace std;
//#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=4e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};


void solve() {
    int n,m;
    cin>>n>>m;
    vector<array<int,3>>ve(m);
    vector<int>g;
    for(int i=0;i<m;++i){
        int u,v,c;
        cin>>u>>v>>c;
        ve[i]={u,v,c};
        g.push_back(c);
    }
    sort(g.begin(),g.end());
    g.resize(unique(g.begin(),g.end())-g.begin());
    vector<vector<int>>f(n+g.size()+1);
    for(auto [u,v,c]:ve){
        c= std::lower_bound(g.begin(), g.end(),c)-g.begin()+n+1;
        f[u].push_back(c);
        f[c].push_back(u);
        f[v].push_back(c);
        f[c].push_back(v);
    }
    int s,t;
    cin>>s>>t;
    vector<int>d(n+g.size()+1,-1);
    d[s]=0;
    queue<int>q;
    q.push(s);
    while(q.size()){
        auto u=q.front();
        q.pop();
        for(auto v:f[u]){
            if(d[v]==-1){
                d[v]=d[u]+1;
                q.push(v);
            }
        }
    }
    cout<<d[t]/2<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
//    init();
    while(t--){
        solve();
    }
    return 0;
}
posted @ 2024-03-12 22:55  bible_w  阅读(80)  评论(0编辑  收藏  举报