今天写了4道题,总体来说收获不错,P1638,P1115,P7072,P2671,都可以说说:
首先是P1638,这道题是双指针的题主要是通i++和j++来移动区间,这个在快速排序里讲过:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int peo[2004];
int dataa[1000003];
int n, m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> dataa[i];
}
int num = 0;
int i = 1;
int l = 1, r = 1;
while (num != m)
{
if (!peo[dataa[i]])
num++;
peo[dataa[i]]++;
r++;
i++;
}
r--;
while (peo[dataa[l]] > 1)
{
peo[dataa[l]]--;
l++;
}
int ansl = l;
int ansr = r;
while (r <= n)
{
r++;
peo[dataa[r]]++;
while(peo[dataa[l]] > 1)
{
peo[dataa[l]]--;
l++;
}
if (ansr - ansl > r - l)
{
ansr = r;
ansl = l;
}
}
cout << ansl << " " << ansr;
return 0;
}
然后是P1115,这个是老问题了,我都写过不知道多少遍了,但是有个大佬的题解给我看蒙了,
通过动态规划来写,简单方便:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
int a, b;
int ans = -10000000;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a;
if (i == 1)
{
b = a;
}
else
b = max(a, b + a);
ans = max(b, ans);
}
cout << ans;
return 0;
}
然后是P7072,这个我学到了新知识,对顶堆,维护一段序列第k个的数,很好用:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <queue>
using namespace std;
priority_queue <int, vector<int>, less<int> > q1; // 大顶堆
priority_queue <int, vector<int>, greater<int> > q2; // 小顶堆
int n, w;
void op(int dataa, int k)
{
if (dataa > q2.top())
{
q2.push(dataa);
}
else {
q1.push(dataa);
}
while (q2.size() > k)
{
q1.push(q2.top());
q2.pop();
}
while (q2.size() < k)
{
q2.push(q1.top());
q1.pop();
}
}
int main()
{
cin >> n >> w;
int tm;
cin >> tm;
q2.push(tm);
printf("%d ", tm);
for (int i = 2; i <= n; i++)
{
int tmp;
cin >> tmp;
int k = max(1, int(w * i / 100));
op(tmp, k);
printf("%d ", q2.top());
}
return 0;
}
P2671这个是数学问题,化简公式来缩小时间复杂度,得记住:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string.h>
using namespace std;
int n, m;
int cnt[100004][2], sum[100005][2], color[100005], nu[100005];
int ans = 0;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> nu[i];
}
for (int i = 1; i <= n; i++)
{
cin >> color[i];
cnt[color[i]][i % 2]++;
sum[color[i]][i % 2] = (sum[color[i]][i % 2] + nu[i]) % 10007;
}
for (int i = 1; i <= n; i++)
{
ans += i * ((cnt[color[i]][i % 2] - 2ll) * nu[i] % 10007 + sum[color[i]][i % 2]);
ans = ans % 10007;
}
cout << ans;
return 0;
}