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)
i∗j−k∗(ai∣aj)的最大值(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)
i∗j−k∗(ai∣aj)
a
i
∣
a
j
ai|aj
ai∣aj这个值最大是
2
∗
n
2*n
2∗n,最小是0
所以后面的值最大为
2
∗
k
∗
n
2*k*n
2∗k∗n,最小为0
而
i
∗
j
i*j
i∗j最大值就是
i
为
n
−
1
,
j
为
n
i为n-1,j为n
i为n−1,j为n时,也就是
n
2
−
n
n^2-n
n2−n,最小肯定就是2,这个值是从前往后单调递增的
在不看后面的值时,一定单调递增,但是减去后面的值时,就不一定了,但是最多减去
2
∗
k
∗
n
2*k*n
2∗k∗n(也可以直接设为200n,因为k最大是100),最少减去0,所以可以想令最后一段区间的最小值减去0,区间最大值减去
2
∗
k
∗
n
2* k*n
2∗k∗n ,所以往前找到找也就是(n-2*k-1)即可
此时i为
(
n
−
2
∗
k
−
1
)
(n-2*k-1)
(n−2∗k−1),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
如果你有任何建议或者批评和补充,请留言指出,不胜感激