一、初赛错题解析
第一题
题目
解析
没啥好说的,记住就好,要多积累。
拓展:
第二题
题目
解析
IMAP: Internet邮件访问协议
FTP:文件传输协议
POP3:邮局协议版本3
SMTP:简单邮件传输协议
解析
二、复赛错题题解
第一题
题目
题解
异或和加法有类似的性质,记录一下前缀异或和数组,表示
异或起来的结果,然后
的区间异或和便可以直接使用
异或上
。
直接枚举所有区间,利用前缀异或和快速计算所有区间的异或和即可。
标程
#include <iostream>
using namespace std;
const int maxN = 5e3 + 5;
int n;
int a[maxN];
int main()
{
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i];
int ans = 0;
for (int i = 1; i <= n; ++i)
{
int res = 0;
for (int j = i; j <= n; ++j)
res ^= a[j], ans = max(ans, res);
}
cout << ans << endl;
return 0;
}
第二题
题目
题解
容易发现,题目中所给的翻转操作可以交换正负号所在的位置,或者是将两个负数化为正数。
那么可以通过若干次交换操作把负号挪到相近的位置,并且将负数两两化为正数。所以,如果序列中有偶数个负数,那么直接把这偶数个负号操作到一起然后一对一对消除即可;如果有奇数个负号,那么最后便会留下一个负号在序列里,通过交换操作把这个负号扔到绝对值最小的数字上即可。
标程
#include <iostream>
using namespace std;
using LL = long long;
const long long maxN = 1e5 + 5;
long long n, cnt;
LL sum;
long long a[maxN];
int main()
{
ios::sync_with_stdio(false);
cin >> n;
long long t = 0;
a[0] = int(1e9) + 1;
for (long long i = 1; i <= n; ++i)
{
cin >> a[i];
sum += abs(a[i]);
if (a[i] < 0)
++cnt;
if (abs(a[t]) > abs(a[i]))
t = i;
}
if (cnt % 2 == 1)
sum -= 2 * abs(a[t]);
cout << sum << endl;
return 0;
}