当日总结
小红定义一个长度为
4
4 的数组为“三带一”,当且仅当其包含三个相同的元素和另一个不同的元素。
现在小红拿到了一个长为
n
n 的数组,他想知道该数组最多包含多少个互不相交的“三带一”连续子数组,请你帮帮他。
输入描述:
第一行输入一个整数
n
(
4
≦
n
≦
2
×
1
0
5
)
n(4≦n≦2×10
5
) 。
第二行输入
n
n 个整数
a1,a2,…,an(1≦ai≦2×105)
a 1,a 2 ,…,a n
(1≦a i ≦2×10
5
) 代表数组的元素。
输出描述:
输出一个整数,代表“三带一”连续子数组的数量。
原代码 #include
include
include
using namespace std;
using ll=long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n;
cin>>n;
map<ll,int>cnt_map;
vector
for(ll i=0;i<n;i++)
{
cin>>num[i];
}
ll cnt=0;
for(ll i=0;i<n-3;i+=4)
{
ll j=i+3;
cnt_map.clear();
for(ll k=i;k<=j;k++)
{
cnt_map[num[k]]++;
}
for(ll m=i;m<=j;m++)
{
if(m==i)
{
if(cnt_map[num[m]]==3)cnt++;
}
else
{
if(cnt_map[num[m]]==cnt_map[num[m-1]]||cnt_map[num[m]]==cnt_map[num[m-2]]||cnt_map[num[m]]==cnt_map[num[m-3]])continue;
if(cnt_map[num[m]]==3)cnt++;
}
}
}
cout<<cnt<<endl;
return 0;
}
核心问题
“三带一” 判断逻辑完全错误
通过 “元素计数等于 3” 就计数,但没验证 “是否只有一个元素出现 3 次、另一个出现 1 次”(比如子数组 [1,1,1,1] 中每个元素计数都是 4,本应不算,但你的逻辑会误判;而 [1,1,1,2] 会因 3 个 1 被重复计数);
内层 for(m) 循环完全多余,同一个 4 长度子数组会被多次计数(比如 [1,1,1,2] 会被计数 3 次)。
遍历逻辑有漏洞
i +=4 意味着只检查 0-3、4-7、8-11… 这些位置的子数组,但如果某个非 4 倍数起始位置的子数组是 “三带一”(比如 1-4),且前面 0-3 不是,你的代码会直接跳过,导致漏统计(贪心策略应是 “找到一个就跳 4 步,没找到就跳 1 步”,而非直接按 4 步遍历)。
效率问题
map 比 unordered_map 慢,统计 4 个元素的计数完全没必要用 map;
内层多余的 for(m) 循环增加无意义的计算。
正确代码#include
include
include <unordered_map> // 替换map,提升效率
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n;
cin >> n;
vector<ll> num(n);
for (ll i = 0; i < n; ++i) {
cin >> num[i];
}
ll cnt = 0;
ll i = 0;
// 贪心遍历:找到三带一则跳4步,否则跳1步
while (i <= n - 4) {
unordered_map<ll, int> cnt_map; // 仅在当前窗口创建,无需clear
// 统计当前4个元素的计数
for (ll k = i; k < i + 4; ++k) {
cnt_map[num[k]]++;
}
// 正确判断“三带一”:恰好一个元素3次,一个元素1次
int has3 = 0, has1 = 0;
bool isValid = true;
for (auto& p : cnt_map) {
if (p.second == 3) has3++;
else if (p.second == 1) has1++;
else { // 出现2次/4次等,直接不合法
isValid = false;
break;
}
}
// 满足条件则计数+1,并跳4步(互不相交)
if (isValid && has3 == 1 && has1 == 1) {
cnt++;
i += 4;
} else {
i++; // 不满足则右移1步继续找
}
}
cout << cnt << endl;
return 0;
}

浙公网安备 33010602011771号