Codeforces Round #466 (Div. 2) ABCD

31 篇文章 1 订阅
14 篇文章 0 订阅

题目链接

A题 解题思路:


输入 n ,d 求数组中,删除多少数后剩下的数组中的最大值与最小值的差值 <= d。求删除的最小数目。

一开始想到双指针,结果真的是想多了(该暴力的时候不暴力) ,n 的大小不超过200 ,n^2 暴力就OK,记得提前排下序,找到符合的最大长度,最后用 n - 最大长度即可。


代码:


#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int ans[10005];

int main(){
    int n , d;
    scanf("%d%d",&n,&d);
    for (int i = 0; i < n; i ++){
        scanf("%d",&ans[i]);
    }
    int mx = 0;
    sort(ans,ans + n);
    for (int i = 0; i < n; i++){
        for (int j = 0 ; j <= i; j ++){
            if (ans[i] - ans[j] <= d){
                mx = max(mx,i - j + 1);
            }
        }
    }
    printf("%d\n",n - mx);
    return 0;
}


题目链接

B题 解题思路:


给予n , a, b, k 求从n走到 1话费最少的钱数,有两种走路方法,一种是 一下走一步,另一种是一下到 n / k 步,但必须能被 k 整除。
第一种话费 a 钱 ,第二种话费 b 钱。

因此我们可以选择走一步或者一下走多部。(直接在代码注释中阐明)

代码:


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;


int main(){
    long long n, k , a ,b; //注意数据范围
    cin>>n>>k>>a>>b;
    long long res = 0;
    while (n != 1){
        if (n % k == 0){  //如果整除,那么可以选择一下走到 n/k 步
            long long t = n / k;  
            if (b >= (n - t) * a){  // 如果一下跳多步所花的钱数都没一步花的钱数少,那么后面的肯定都是一步一步走
                res += (n - 1) * a;
                break;
            }
            else{  //如果比一步一步花的钱数多,那么我们一次性走到 n / k 处
                res += b;
                n = t;
            }
        }
        else{ // 如果不能整除
            res += (n % k ) *a;   // 那么直接计算到能整除时候的位置 进行 % 运算  (原先一步一步走,结果超时了)
            n -= n % k;
           
        }
    }
    cout<<res<<endl;
    return 0;
}


题目链接

C题 解题思路:


给予n , k 然后给出长度为 n 的字符串,让我们求出长度为 k 的字符串 让他的字典序比给定的字符串大,在这个要求下,让他最小。(字符只能用题目给定字符串中的字符)

分为两种情况:

  1. 当 k > n 时: 我们之间在原给的字符串中加入k - n 个原给字符串中的最小字母。
  2. n >= k 那么我们截取长度为 n 的前 k 个字符,从后向前找,找出第一个不是最大字符的字符位置,将其变为比他大一的字符,然后后面位置的字符全都改成最小的字符。

(这里的最大最小都是根据给定的原本字符串含有的字符定义的大小)


代码:


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

char ans[30];

int main(){
    int n , k;
    cin>>n>>k;
    string St;
    cin>>St;
    string St1 = St;
    sort(St1.begin(),St1.end());
    int m = 0;
    ans[m] = St1[0];
    for (int i = 1; i < n ; i ++){
        if (ans[m] != St1[i]){
            ans[++m] = St1[i];
        }
    }
    if (k > n){
        for (int i = 0; i < n; i ++){
            printf("%c",St[i]);
        }
        for (int i = 0; i < k - n; i++){
            printf("%c",ans[0]);
        }
        printf("\n");
    }
    else{
        string St2 = "";
        for (int i = 0; i < k ;i++){
            St2 += St[i];
        }
        for (int i = k - 1; i >= 0; i --){
            char s = St[i];
            if (s != ans[m]){
                for (int j = m - 1; j >= 0; j--){
                    if (ans[j] == s){
                        St2[i] = ans[j + 1];
                        for (int q = i + 1; q < k ; q ++){
                            St2[q] = ans[0];
                        }
                        cout<<St2<<endl;
                        return 0;
                    }
                }
                
            }    
        }
    }
    
    return 0;
}


题目链接

解题思路:


给予一个n,然后给予一个长度为 n 的 数组a ,然后给予一个长度为 n 的字符串 b。
题目中说明:
在这里插入图片描述
因此当 i >= 5时候,我们判断 b字符串中 i 位置的数是否和前一个相同:

  1. 如果相同:那么继续进行
  2. 如果不同:那么判断他的前四个是否相等,如果相等,并且为 1 那么执行第一个操作,如果为2,那么进行第二个操作,否则什么都不进行

然后循环就OK,本题是随意输出结果 (只要符合答案就OK)

初值很重要,-1e9 和 1e9 ,最后不要忘记 + 1 和 - 1 因为是 大于号和小于号。


代码:


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 500010;

int ans[N];

int main(){
    int n;
    scanf("%d",&n);
    for (int  i = 0; i < n; i++){
        scanf("%d",&ans[i]);
    }
    string b;
    cin>>b;
    int l = -1e9;
    int r = 1e9;
    for (int i = 4; i < n ;i++){
        if (b[i] != b[i - 1]){
            if (b[i - 1] == b[i - 2] && b[i - 2] == b[i -3] && b[i - 3] == b[i - 4]){
                if (b[i - 4] == '0') {
                    for (int j = i - 4; j <= i; j ++){
                        l = max(l,ans[j]);
                    }
                }
                else{
                    for (int j = i - 4; j <= i; j++){
                        r = min(r,ans[j]);
                    }
                }
            }
        }
    }
    printf("%d %d\n",l + 1,r - 1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值