2023.11.10 测试复盘
$2023.11.10$ 测试复盘
总分:$100+50+70=220$
一道水题。直接模拟即可。时间复杂度:$O(Tn)$
${\color{#52C41A} \texttt{AC}}$ Code:
#include <cstdio>
#include <cstring>
using namespace std;
char s[103];
int main() {
int _;
scanf("%d", &_);
while(_--) {
scanf("%s", s + 1);
int cntu = 0, cntl = 0, n = strlen(s + 1);
for(int i = 1; i <= n; ++i)
if('A' <= s[i] && s[i] <= 'Z')
++cntu;
else if('a' <= s[i] && s[i] <= 'z')
++cntl;
if(cntu > cntl)
for(int i = 1; i <= n; ++i)
if('a' <= s[i] && s[i] <= 'z')
putchar(s[i] - 32);
else
putchar(s[i]);
else
for(int i = 1; i <= n; ++i)
if('A' <= s[i] && s[i] <= 'Z')
putchar(s[i] + 32);
else
putchar(s[i]);
putchar('\n');
}
return 0;
}
这道题是三道题中最难的一道(反正老师和大部分同学这么认为)。我用枚举+前缀和优化拿到 $50 \text{pts}$,时间复杂度 $O(n^2)$。正解是枚举第二条分界线,然后判断是否存在合理的第一条分界线,最后根据乘法原理可得答案。
${\color{#52C41A} \texttt{AC}}$ Code:
#include <cstdio>
#include <map>
using namespace std;
using LL = long long;
const int N = 100003;
map<int, int> mp;
LL a[N], qzh[N], hzh[N];
int main() {
int n;
LL tot = 0, ans = 0;
scanf("%d", &n);
if(n < 3)
{
putchar('0');
return 0;
}
for(int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
tot += a[i];
qzh[i] = qzh[i - 1] + a[i];
}
for(int i = n; i >= 1; --i)
{
hzh[i] = hzh[i + 1] + a[i];
++mp[hzh[i]];
}
--mp[hzh[1]];
for(int i = 1; i < n - 1; ++i)
{
--mp[hzh[i + 1]];
if(qzh[i] * 3 == tot)
ans += mp[qzh[i]];
}
printf("%lld", ans);
return 0;
}
这道题难度中等,主要考验思维,代码实现比较简单。思路是:
-
分析可知,第一个数要么是 $0$ 要么是 $3$。如果 $n < 3$,则直接输出 $0$。
-
然后可知,对于第 $i$ 个数,我们要找 $a_j$ 和 $a_k$ 满足 $a_j < a_i < a_k (1 \le j < i < k \le n)$。而这个可以通过
打表预处理得到。
时间复杂度:$O(n)$
${\color{#52C41A} \texttt{AC}}$ Code:
#include <cstdio>
using namespace std;
const int N = 100003;
int min1[N]{0, 1}, min2[N], max1[N]{0, 1}, max2[N], num[N];
int main() {
int n;
scanf("%d", &n);
if(n < 3)
{
printf("0");
return 0;
}
for(int i = 1; i <= n; ++i)
scanf("%d", &num[i]);
for(int i = 2; i < n; ++i)
{
if(num[max1[i - 1]] > num[i])
max1[i] = max1[i - 1];
else
max1[i] = i;
if(num[min1[i - 1]] < num[i])
min1[i] = min1[i - 1];
else
min1[i] = i;
}
min2[n] = max2[n] = n;
for(int i = n - 1; i > 0; --i)
{
if(num[max2[i + 1]] > num[i])
max2[i] = max2[i + 1];
else
max2[i] = i;
if(num[min2[i + 1]] < num[i])
min2[i] = min2[i + 1];
else
min2[i] = i;
}
int i;
for(i = 2; i < n; ++i)
{
if(num[max1[i - 1]] > num[i] && num[max2[i + 1]] > num[i])
{
printf("3\n%d %d %d", max1[i - 1], i, max2[i + 1]);
break;
}
if(num[min1[i - 1]] < num[i] && num[min2[i + 1]] < num[i])
{
printf("3\n%d %d %d", min1[i - 1], i, min2[i + 1]);
break;
}
}
if(i == n)
printf("0");
return 0;
}

浙公网安备 33010602011771号