A. Cherry
很好玩的一道思维题 给出n个数字的数组 求最大的对于[l, r]中 max(al, al + 1 ,… , ar) * min(al, al + 1, … , ar) 贪心来想可以得出遍历一遍求相邻两个元素乘积的最大值
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll n, a[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
ll ans = -1;
for (int i = 2; i <= n; i ++ )
ans = max(ans, a[i] * a[i - 1]);
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while (T -- )
{
solve();
}
return 0;
}
B. Cobb
这个题 k< min(n, 100) 所以k*(ai | aj) 最大为200*n 从n-200开始暴力比较求ans就好了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n, k;
ll a[N];
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i ++ ) scanf("%lld", &a[i]);
ll ans = 2 - k * (a[1] | a[2]);
if (n <= 200)
for (ll i = 1; i <= n; i ++ )
for (ll j = i + 1; j <= n; j ++ )
ans = max(ans, i * j - k * (a[i] | a[j]));
else
for (ll i = n - 200; i <= n; i ++ )
for (ll j = i + 1; j <= n; j ++ )
ans = max(ans, i * j - k * (a[i] | a[j]));
printf("%lld\n", ans);
}
return 0;
}
C. Mikasa
自我感觉这场c题对于我来说应该是学到最多的
首先 a ^ b = c -> a ^ c = b 这是异或交换律
假设ans为满足题意的值 即在序列中未出现的值
对于题目中 我们要去找ans的最小值 n ^ x = ans
假设ans从序列中出现过 则有x属于(1, m)
如果ans从序列中未出现过 则有 x > m
通过交换律可以得到 n ^ ans = x 若想满足题意 则要求 x>m 即 x>=m+1
这时候就容易考虑了 让m = m+1
对于每一位的 ni, mi 都要有 ni ^ ansi >= mi:
当 ni == mi 时 ansi可以取到0
当 ni != mi && ni = 1时候 mi = 0 这时候ansi可以取到0
但是当 ni != mi && mi = 1, ni = 0 的时候 ansi必须取到1从而使 ni ^ ansi >= mi
在第三种情况后每次n都要加上这一位 当 在第i位后 n>m的时候 包括第i位及之后的所有位 ans都可以取到0
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
ll n, m;
cin >> n >> m;
m ++ ;
ll ans = 0;
for (int i = 30; i >= 0 && n < m; i -- )
{
if (n >> i == m >> i) continue;
if (m >> i) ans |= 1 << i, n |= 1 << i;
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T -- )
{
solve();
}
return 0;
}
D. Diane
这是一个字符串构造问题 (一般都可以构造出与一串相同字母有关的字符串) 要求给出一个n 构造一个长度为n的最小字母字符串 对于这个字符串要求每个子字符串在此字符串中出现次数都为奇数次
感觉像是找规律题 对于一个长度为n的相同字母字符串 它的某种字符串长度假设为x 则这种子字符串必然出现了n-x+1次 所以可以在中间夹杂一个其他字母 然后使得左右两边长度差1
对于n为偶数情况下 中间可以夹一个b 对于n为奇数情况下中间夹杂一个bc
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve()
{
ll n;
cin >> n;
if (n == 1)
{
cout << 'a' << endl;;
}
else
{
for (int i = 1; i <= n / 2; i ++ ) cout << 'a';
cout << 'b';
if (n & 1) cout << 'c';
for (int i = 1; i <= n / 2 - 1; i ++ ) cout << 'a';
cout << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while (T -- )
{
solve();
}
return 0;
}