Codeforces Round #698 (Div. 2) A~C题解

写在前边

链接:Codeforces Round #698 (Div. 2)
又是自闭的一场比赛,C题补了一天终于明白了一些,真的好自闭好自闭。
今晚还有一场,加油喽。

A. Nezzar and Colorful Balls

链接:A题链接

题目大意:

给定一个单调不减的序列,现在往上边涂颜色,要求涂颜色后,选中其中任意一种颜色,去除所有其他颜色的数字后剩下的数字组成的序列是严格递增的,问至少需要几种颜色可以达到这种效果。

思路

首先想到,如果想要达到题目要求,对于这类似1 1 1 1这种连续相同的序列,肯定不能用一种颜色,因子就推出需要的颜色种数就是序列中数目最多的数字个数。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <unordered_map>

using namespace std;

#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;

void solve() {
    int n;
    cin >> n;
    unordered_map<int, int> hash;
    for (int i = 0; i < n; i++) {
        int c;
        cin >> c;
        hash[c]++;
    }
    int res = 0;
    for (auto it : hash) {
        res = max(res, it.second);
    }
    cout << res << endl;
}

int main()
{
    //ios::sync_with_stdio(false), cin.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
} 

B. Nezzar and Lucky Number

链接:B题链接

题目大意:

选定一个幸运数d[1,9],凡是数字中带有它都是幸运数,如选定7,那么1727...也都是幸运数,同时,由幸运数加和组成的数也都是幸运数,例如54=27+27,因此54也是幸运数,现在要求快速判断一个数是否是幸运数。

思路

推了好久,一个数如果是幸运数,大致推出一个数是幸运数那么必然可以表示:number=10k+dn,k0,d1的形式,因此判断一个数是否是幸运数就让它一直减d,直到剩下010,那么就可以判断是幸运数了,但是对于大数这样做铁定超超时,而对于大数,还有一条性质,即如果number10d,那么number必然是一个幸运数,下面给出证明
设一个区间:[10d,10d+9]
那么对于这样一个区间的数就包含了一个d了,因此这个区间的数就都是幸运数,而对于每一个数k>10d+9,我们可以让它不断地减去d那么一定可以落到这个区间,因此number10d,则number一定是幸运数,证毕。

所以对于大数可以直接判断是否10d,小数直接枚举即可。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <unordered_map>
#include <string>
 
using namespace std;
 
#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>
 
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;
 
const int N = 1E4 + 10;
int a[N];
 
void solve() {
    int q, d, idx;
    scanf("%d%d", &q, &d);
    for (int i = 0; i < q; i++) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < q; i++) {
        if (a[i] >= 10 * d) {
            puts("YES");
        } else {
            int temp = a[i];
            temp -= d;
            //一直减d减到10的倍数
            while (temp % 10 != 0 && temp >= 0) {
                temp -= d;
            }
            if (temp >= 0 && temp / 10 >= 0) {
                puts("YES");
            } else {
                puts("NO");
            }
        }
    }
}
 
int main()
{
    //ios::sync_with_stdio(false), cin.tie(0);
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }

    return 0;
} 

C. Nezzar and Symmetric Array

链接:C题链接

题目大意:

给定一个有2n个数数组di,问我们是否可以构造出一个aia满足以下条件:

  1. a2n个数各不相同
  2. 对于任意一个数,1i2n,存在一个数1j2n,这两个数满足ai=aj

能使得di=j=12n|aiaj|

思路

a中的数可以说是"对称"的,即一正一负,对于一个数对x与其中一个数对(y,y)就有|xy|+|x+y|,同理对于x则有|xy|+|x+y|,而|xy|+|x+y|=|xy|+|x+y|,所以可见d中得数对是成对出现的,同时ai又是两两不同,那么d中相同的数的对数只能为1,且不能超过1又因为任意两个相同的数相加是一定偶数,因此d中的数肯定都是偶数, 所以对于|xy|+|x+y|

x>y时,则|xy|+|x+y|=2x
x<y时,则|xy|+|x+y|=2y

因此可以发现对于一个x与一个数对(y,y),对di得贡献就是|xy|+|x+y|=2max(x,y), 同理x也是。

所以对于题目中所给公式di=j=12n|aiaj|,公式就变成了di=j=12nmax(|ai|,|aj|),而又因为xxdi的贡献相同,因此我们光看正的那一部分,所以公式又变成了di=2j=1nmax(|ai|,|aj|)

对于最大的数ai那么组成的di肯定也是最大的,di=a[i]2n,所以得a[i]=di2n
对于次大的数ai1,因为比它大的只有ai,所以di1=a[i1]2(n1)+2a[i],即a[i1]=di12a[i]2(n1)
...
以此类推,还要判断一下计算出来的a是否已经存在, 或者其他情况。

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>

using namespace std;

#define Inf 0x3f3f3f3f
#define PII pair<int, int>
#define P2LL pair<long long, long long>

typedef long long LL;
typedef unsigned long long ULL;
typedef vector<long long> VLL;
typedef vector<int> VI;

typedef long long LL;

const int N = 1E5 + 10;
LL n;

void solve() {
    cin >> n;
    map<LL, LL, greater<int> > mp;
    map<LL, bool> vis;
    for (int i = 0; i < n * 2; i++) {
        LL c;
        cin >> c;
        mp[c]++;
    }
    LL k = 0, last = 0;
    for (auto it : mp) {
        LL d_value = it.first, cnt = it.second;
        if (cnt & 1 || d_value & 1 || cnt > 2) { //如果没有成对出现 或者 出现奇数 出现次数大于2
            puts("NO");
            return;
        }
        LL up = (d_value - last * 2) / 2;   
        LL down = n - k;
        if (up % down != 0) {
            puts("NO");
            return;
        }
        up /= down;
        if (vis.count(up) || up <= 0) {
            puts("NO");
            return;
        }
        vis[up] = true;
        last += up;
        k++;
    }
    puts("YES");
}

int main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    system("pause");
    return 0;
}
posted @   Xxaj5  阅读(125)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示