Codeforces Round #596 (Div. 2)(第三场)

Preface

我要开始打Codeforces了,这是我的第三场比赛,本来以为可以快速上分的,谁知在pupil的路上越走越远。

本场战绩:
Cost Time: 2 hours
Solved: 1.5
Rank: 3023
Rating: -31

Question

A. Forgetting Things
题目大意:输入小于10的正整数a和b,输出任意分别以a和b开头的两个连续整数,如果不存在这样的数,则输出"-1"。
解法:可以发现只有当 a a 等于 b b ,当 a + 1 a + 1 等于 b b 以及当 a a 等于 9 9 b b 等于 1 1 这三种情况下可以找到答案。

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 +10;
int a, b;
/*
 * 省略了快读和快写
 */
int main()
{
    read(a) ,read(b);
    if (a == b) {
        cout << a * 10 + 1 << " " << b * 10 + 2 << endl;
    } else if (a + 1 == b) {
        cout << a * 10 + 9 << " " << b * 10 << endl;
    } else if(a == 9 && b == 1) {
        cout << a * 10 + 9 << " " << b * 100 << endl;
    } else {
        writeln(-1);
    }
    return 0;
}

B. TV Subscriptions
题目大意:有n天,每天电视台都播放着编号为 a i ( 1 a i k ) a_i(1 \leq a_i \leq k) 的节目,现在要求至少要订阅多少个节目才能使连续 d d 天有节目看?

解法:用一个长度为 d d 的区间去扫描记录节目的数组,同时维护一个记录区间节目数的变量,扫描完即可得到最小的节目数。

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 +10;
const int N = 1e6 + 10;
int T, n, k, d;
int a[maxn], vis[N];
/*
 * 省略了快读和快写
 */
int main()
{
    read(T);
    while(T--) {
        read(n); read(k); read(d);
        for (int i = 1; i <= n; i++) {
            read(a[i]);
            vis[a[i]] = 0;
        }
        int ans = inf, t = 0;
        for (int i = 1; i <= d; i++) {
            if (!vis[a[i]]) t++;
            vis[a[i]]++;
        }
 
        ans = min(ans, t);
 
        for (int  i = d + 1; i <= n; i++) {
            vis[a[i - d]]--;
            if (!vis[a[i - d]]) t--;
            if (!vis[a[i]]) t++;
            vis[a[i]]++;
            ans = min(ans, t);
        }
        writeln(ans);
    }
    return 0;
}

C. p-binary
题目大意:给定n和p的值,求出最小的k值,可以使得 n = i = 1 k ( 2 x i + p ) n= \sum^k_{i=1}(2^{x_i}+p) 成立。
解法:上式可转化为:
n k p = i = 1 k 2 x i n-k*p= \sum^k_{i=1}2^{x_i}
t = n k p t=n-k*p ,由二进制转十进制的“位权法”,我们可以想到考虑 t t 的二进制表示。

  1. t t 的二进制数中1的个数大于 k k 时, k k 不符合条件。
  2. t t 的二进制数中1的个数小于或等于 k k 时,我们可以通过分解使得 2 x i 2^{x_i} 的个数等于 k k 。(比如 2 5 = 2 4 + x 4 2^5=2^4+x^4 )。

于是,我们就可以从小到大遍历 k k 的值,最先找到答案便是我们要找的。注意:当出现 t < k t < k 这种情况时,说明不存在满足条件的 k k 值。

关于 k k 的上限,由上述可知,当 c a l ( n k p ) k cal(n-k*p) \leq k 就会得到结果,而 n 1 0 9 , 1000 p 1000 n \leq 10^9,-1000\leq p \leq 1000 ,所以 k k 的值必定不会超过31。

/**
 * Author: Veggie
 */
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 +10;
int a, b;
/*
 * 省略了快读和快写
 */
int cal(int x) {
    int cnt = 0;
    while (x) {
        if (x & 1) cnt ++;
        x >>= 1;
    }
    return cnt;
}

int main()
{
    read(a), read(b);
    int t;
    for (int k = 1; k < 32; k++) {
        t = a - k * b;
        if (t < k) break;
        if (cal(t) <= k) {
            writeln(k);
            return 0;
        }
    }
    writeln(-1);
    return 0;
}

Rating View

在这里插入图片描述

发布了59 篇原创文章 · 获赞 103 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42292229/article/details/102866862