Codeforces Round #735 (Div. 2)(补题)

A. Cherry

在这里插入图片描述在这里插入图片描述
题意: 一个区间最大值乘以最小值,让你求出这个乘积的最大值
思路: 直接枚举相邻的数即可,因为相邻的数肯定一个大一个小,直接乘起来然后取最大值即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
int a[N];
int main() {
    int t;
    scanf("%d",&t);
    while(t--) {
        int n;
        ll res=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            res=max(res,(ll)a[i]*a[i-1]);
        }
        printf("%lld\n",res);
    }
    return 0;
}

B. Cobb

在这里插入图片描述
在这里插入图片描述
题意 : 让你求 i ∗ j − k ∗ ( a i ∣ a j ) i* j-k*(ai|aj) ijk(aiaj)的最大值(j>i)
思路: 关键信息在于k的范围和a[]的范围,k限制在100之间,而a[i]限制在了n之间(而不是任意值,一开始没注意这个点)
f ( i , j ) f(i,j) f(i,j)= i ∗ j − k ∗ ( a i ∣ a j ) i* j-k*(ai|aj) ijk(aiaj)
a i ∣ a j ai|aj aiaj这个值最大是 2 ∗ n 2*n 2n,最小是0
所以后面的值最大为 2 ∗ k ∗ n 2*k*n 2kn,最小为0
i ∗ j i*j ij最大值就是 i 为 n − 1 , j 为 n i为n-1,j为n in1,jn时,也就是 n 2 − n n^2-n n2n,最小肯定就是2,这个值是从前往后单调递增的
在不看后面的值时,一定单调递增,但是减去后面的值时,就不一定了,但是最多减去 2 ∗ k ∗ n 2*k*n 2kn(也可以直接设为200n,因为k最大是100),最少减去0,所以可以想令最后一段区间的最小值减去0,区间最大值减去 2 ∗ k ∗ n 2* k*n 2kn ,所以往前找到找也就是(n-2*k-1)即可
此时i为 ( n − 2 ∗ k − 1 ) (n-2*k-1) (n2k1),j为n,那么此时就找这个区间就行
也可以假定k就为100,直接暴力找
(个人理解)

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
#define ll long long
#define inf 0x3f3f3f3f3f3f3f
int a[N];
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--) {
        int n, k;
        ll res = -inf;
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        for (int i = max(1, n - 2 * k); i <= n; i++) {
            for (int j = i + 1; j <= n; j++) {
                res = max(res, (ll)i * j - k * (a[i] | a[j]));
            }
        }
        cout << res << '\n';
    }
    return 0;
}

C. Mikasa

在这里插入图片描述
题意: 给一个n和m,使n^ 0 n^1… n^m,让你求出这些值的MEX值
思路: 因为n^ [0,m],所以要想找到一个MEX值(原有数中不存在的最小值),那么一定是n^p,p>m,要想让p>m,那么只需要在m二进制的情况下,从前往后枚举每一位,枚举到当前这位时,在对应位置+1,这样出现的数一定是>m,然后要想总体异或值最小,一定对应位置后面的二进制是一样的,这样疑惑对应位置就是0,这样枚举每一位,取异或值最小值即可。

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, m;
        scanf("%d%d", &n, &m);
        int res = inf;
        for (int k = 30; k >= 0; k--) {
            int x = (n >> k) << k;
            int y = ((m >> k) + 1) << k;
            res = min(res, x ^ y);
        }
        printf("%d\n", res);
    }
    return 0;
}

D. Diane

在这里插入图片描述
题意: 让你输出长度为n的字符串,其字符串的子串在原串出现的次数必须是奇数
思路: 分奇偶来讨论(为了方便讲解),一段重复出现的长度为6的"aaaaaa",可以发现,其子串’aaaaa’出现次数是2,‘aaaa’出现次数是3,'aaa’出现次数是4…‘a’出现次数是6,
重复单一的字符串其子串出现次数是len-zlen+1,其奇偶性是交替出现的,那么就可以考虑将这种重复单一的字符串结合一下,让其子串的出现次数总为奇数,也就是构造长度为x+1和x的重复字符串,在中间在加一个b,如果是奇数那在后面再加一个c

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n / 2; i++) {
            cout << "a";
        }
        cout << "b";
        for (int i = 0; i < n / 2 - 1; i++) {
            cout << "a";
        }
        if (n % 2 == 1 && n > 1) cout << "c";
        printf("\n");
    }
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值