Codeforces Round #687 (Div. 2, based on Technocup 2021 Elimination Round 2)

Codeforces Round #687 (Div. 2, based on Technocup 2021 Elimination Round 2)

传送门(点击传送

A. Prison Break

题意:
  有一个 n × m n × m n×m 大小的监狱,每一个坐标 ( i , j ) (i, j) (i,j) 的位置都是一个牢房单间,现在位于 ( r , c ) (r,c) (r,c) 的位置有一个密道,现在每个人每秒钟只能移动到相邻的牢房单间,问整座监狱的所有犯人都移动到有密道的牢房单间需要多长时间。
  
思路:
  最远只可能是牢房的四个角,而且每秒钟只能移动到相邻位置,所以四个角的坐标 ( n , m ) (n,m) (n,m) ( 1 , m ) (1,m) (1,m) ( n , 1 ) (n,1) (n,1) ( 1 , 1 ) (1,1) (1,1) ( r , c ) (r, c) (r,c)的曼哈顿距离的最大值就是需要的时间。( t t t 组数据)
  
代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t,n,m,r,c,ans;
    cin>>t;
    while(t--){
    
    
        cin>>n>>m>>r>>c;
        ans=0;
        ans=max(abs(n-r)+abs(m-c),ans);
        ans=max(abs(1-r)+abs(m-c),ans);
        ans=max(abs(n-r)+abs(1-c),ans);
        ans=max(abs(1-r)+abs(1-c),ans);
        cout<<ans<<endl;
    }
    return 0;
}

B. Repainting Street

题意:
  有一条路上一共有按顺序排列的 n n n 个房子,每个房子都有一个颜色 c i c_i ci,如果让街道变得漂亮,就得需要所有的房子的颜色得到统一。现在粉刷匠每天最多能将连续的 k k k 个房子粉刷成想得到的颜色。问让街道变漂亮最少需要多少天。( t t t 组数据)
  
思路:
  因为 c i c_i ci 最大只有100,即最多只有100种颜色,所以枚举把所有房子刷成每一种颜色需要多少天,取最小值就是答案。枚举每一种颜色时,从左到右枚举房子,若当前房子颜色不为该枚举颜色,假设当前位置为 i i i,则 [ i , i + k − 1 ] [i,i+k-1] [i,i+k1] 的房间将耗费一天的时间粉刷。
  
代码:

#include<bits/stdc++.h>
using namespace std;
int num[100005];
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t,n,k,ans;
    cin>>t;
    while(t--){
    
    
        ans=0x7fffffff;
        cin>>n>>k;
        for(int i=1;i<=n;i++){
    
    
            cin>>num[i];
        }
        for(int i=1;i<=100;i++){
    
    
            int cont=0;
            for(int j=1;j<=n;j++){
    
    
                if(num[j]!=i){
    
    
                    j+=k-1;
                    cont++;
                }
            }
            ans=min(ans,cont);
        }
        cout<<ans<<endl;
    }
    return 0;
}

C. Bouncing Ball

题意:
  一个游戏有长度为 n n n 的空间,在每个位置都可能有一个跳台,初始情况由题目输入,现在有一个弹跳能力为 k k k 的球,它最一开始会落在 p p p 的位置,然后会依次弹跳至 p + k p+k p+k p + 2 k p+2k p+2k,……,直至跳出长度为 n n n 的空间。但是球只有在弹跳位置有跳台才可以弹起,否则无法继续弹跳。现在游戏设计师要将关卡设计成球能够跳出长度为 n n n 的空间,他有两种操作,第一种:花费 x x x 秒钟在某一位置制造一个跳台。第二种:花费 y y y 秒钟将最左边的空间去掉,形成大小为 n − 1 n-1 n1 的空间。现在要求设计师花费最短的时间将题图更改符合要求,且空间大小不能小于 p p p,问最短的时间为多少。
  
思路:
  从右到左依次遍历,设 d p [ i ] dp[i] dp[i]为球弹到位置 i i i 时,如果要完成关卡所需任务设计师改造地图需要多长时间。那么对于右边的 k k k 个位置,如果 s [ i ] s[i] s[i] 1 1 1,则需要 0 0 0 秒,若 s [ i ] s[i] s[i] 0 0 0 则需要制造一个跳台,即需要 x x x 秒,然后对于剩下的位置有转移方程若 s [ i ] = 0 s[i]=0 s[i]=0 d p [ i ] = d p [ i + k ] + x dp[i]=dp[i+k]+x dp[i]=dp[i+k]+x,若 s [ i ] = 1 s[i]=1 s[i]=1 d p [ i ] = d p [ i ] dp[i]=dp[i] dp[i]=dp[i],那么我们有了球弹到每一个位置时所完成任务需要的时间,那么我们就假设这些位置都是球第一次弹跳的位置p,计算一下对应需要删除掉的空间即可。所有可能解的最小值就是最终答案。需要注意边界的设置。
  
代码:

#include<bits/stdc++.h>
using namespace std;
int dp[100005];
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t,n,p,k,x,y,ans;
    string s;
    cin>>t;
    while(t--){
    
    
        ans=0x7fffffff;
        cin>>n>>p>>k>>s>>x>>y;
        memset(dp,0,sizeof(dp));
        for(int i=n-1,j=1;i>=p-1;i--,j++){
    
    
            if(j<=k){
    
    
                if(s[i]=='0') dp[i]=x;
            }else{
    
    
                if(s[i]=='0') dp[i]=dp[i+k]+x;
                else dp[i]=dp[i+k];
            }
        }
        for(int i=p-1,j=0;i<=n-1;i++,j++){
    
    
            ans=min(ans,dp[i]+j*y);
        }
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/blaction/article/details/110727689