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 a等于 b b b,当 a + 1 a + 1 a+1等于 b b b以及当 a a a等于 9 9 9 b b b等于 1 1 1这三种情况下可以找到答案。

#include 
 
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) ai(1aik)的节目,现在要求至少要订阅多少个节目才能使连续 d d d天有节目看?

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

#include 
 
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=i=1k(2xi+p)成立。
解法:上式可转化为:
n − k ∗ p = ∑ i = 1 k 2 x i n-k*p= \sum^k_{i=1}2^{x_i} nkp=i=1k2xi
t = n − k ∗ p t=n-k*p t=nkp,由二进制转十进制的“位权法”,我们可以想到考虑 t t t 的二进制表示。

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

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

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

/**
 * Author: Veggie
 */
#include 

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

Codeforces Round #596 (Div. 2)(第三场)_第1张图片

你可能感兴趣的:(Codeforces Round #596 (Div. 2)(第三场))