Codeforces Round #466 (Div. 2)

A. Points on the line
题意:给你一个序列,让你求去除最少的数字,保证剩下的序列: 最大值-最小值<=k;
分析:
直接暴力;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;

const int MAXN = 1e3 + 5;
int a[MAXN], b[MAXN], c[MAXN];

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

B. Our Tanya is Crying Out Loud
题意:给你四个值n,k,A,B,求让n变成1的最小花费。花费方式有两种:第一,让n减去1花费A硬币;第二,让n除以k(n%k=0的时候)花费B硬币;
分析:
直接模拟,注意k==1时,不会花费B硬币;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;

const int MAXN = 1e3 + 5;

int main() {
    LL n, k, A, B, ans = 0;
    scanf("%lld %lld %lld %lld", &n, &k, &A, &B);
    if(k == 1) { //TLE test6
        printf("%lld\n", A * (n - 1));
        return 0;
    }
    while(n != 1LL) {
        if(k > n) {
            ans += (n - 1) * A;
            break;
        }
        if(n % k == 0) {
            LL cnt = n - n / k;
            ans += min(cnt * A, B);
            n /= k;
        }
        else {
            LL cnt = n % k; //这个做个小小的优化
            ans += A * cnt;
            n -= cnt;
        }
    }
    printf("%lld\n", ans);
    return 0;
}

C. Phone Numbers
题意:给你一个小写英文字符串,再给你一个k值,让你输出一条k个字符的字符串。相应长度比较起来,这个字符串要比输入的字符串字典序大,且是所有字典序大中的最小的那个;
分析:
处理成进制问题就行了,多少种字符就是多少进制,注意映射关系;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;

const int MAXN = 1e5 + 5;
int a[MAXN], b[MAXN];
char str[MAXN], ch[MAXN], s[MAXN], c[MAXN];

int main() {
    int n, m;
    scanf("%d %d\n", &n, &m);
    scanf("%s", str);
    strcpy(ch, str);
    int p = 0, len = strlen(str);
    sort(ch, ch + len);
    for(int i = 0; i < len; ++i) {
        if(ch[i] != ch[i + 1]) {
            a[ch[i]] = p;
            s[p++] = ch[i];
        }
    }
    if(len < m) {
        printf("%s", str);
        for(int i = 0; i < m - len; ++i) {
            printf("%c", s[0]);
        }
        puts("");
        return 0;
    }
    bool flag = true;
    for(int i = m - 1; i >= 0; --i) {
        if(str[i] == s[p - 1] && flag) {
            c[i] = s[0];
        }
        else if(flag) {
            c[i] = s[a[str[i]] + 1];
            flag = false;
        }
        else {
            c[i] = str[i];
        }
    }
    for(int i = 0; i < m; ++i) {
        printf("%c", c[i]);
    }
    puts("");
    return 0;
}

D. Alena And The Heater
题意:根据b序列,和对应的a序列,找出满足条件的L和R。b序列构造条件:
bi = 0 if ai, ai - 1, ai - 2, ai - 3, ai - 4 > r and bi - 1 = bi - 2 = bi - 3 = bi - 4 = 1
bi = 1 if ai, ai - 1, ai - 2, ai - 3, ai - 4 < l and bi - 1 = bi - 2 = bi - 3 = bi - 4 = 0
bi = bi - 1 otherwise
分析:
看懂题意后就是模拟+暴力;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;

const int MAXN = 1e5 + 5;
int a[MAXN], c[MAXN], d[MAXN];
char b[MAXN];

int main() {
    int n;
    scanf("%d\n", &n);
    for(int i = 0; i < n; ++i) {
        scanf("%d\n", &a[i]);
    }
    scanf("%s", b);
    for(int i = 4; i < n; ++i) { //预处理一下区间最值
        int ans = -1e9, cnt = 1e9;
        for(int j = i - 4; j <= i; ++j) {
            ans = max(ans, a[j]);
            cnt = min(cnt, a[j]);
        }
        c[i] = cnt;
        d[i] = ans;
    }
    int L = -1e9, R = 1e9;
    int minn = L, maxn = R;
    for(int i = 4; i < strlen(b); ++i) {
        bool flag = true;
        char ch = b[i];
        for(int j = i - 4; j < i; j++) {
            if(ch == b[j]) {
                flag = false;
                break;
            }
        }
        if(flag) {
            if(ch == '0') R = min(R, c[i]);
            else L = max(L, d[i]);
        }
    }
    printf("%d %d\n", L + 1, R - 1);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值