数组下标大奥秘
杰哥的疑问
题目
杰哥给出了一个数m。杰哥想知道,这个数组中有多少对数的和等于给定的数。
即有多少对 (i,j)满足 ai+aj=m,且1 <=i < j <= n。
输入描述:
第一行输入两个正整数 n,m 分别表示数组的元素个数,以及杰哥给定的数。(1≤n≤10^6, 0≤m≤10^9)
第二行输入 n 个正整数,第 i 个正整数为 ai(0≤ai≤10^9)。
输出描述:
输出一行一个正整数,表示满足条件的对的数量。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
unordered_map<int, int> mp;
int n, m;
int main(){
cin >> n >> m;
ll res = 0;
for(int i = 1; i<=n; i++){
int x; cin >> x;
res += mp[m-x];
mp[x]++;
}
cout << res;
return 0;
}
单调队列——滑动窗口
题目:
给定一个大小为 n≤10^6 的数组。
有一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。
你只能在窗口中看到 k 个数字。
每次滑动窗口向右移动一个位置。
求每个窗口中数的最大值和最小值。
输出描述:
输出两行,第一行输出所有窗口的最小值,第二行输出最大值。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6+6;
int a[N];
int q[N]; // 记录的是下标
int tt, hh, n, k;
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> k;
for(int i = 0; i < n; i++)cin >> a[i];
hh = 0, tt = -1; //用数组模拟队列,tt从-1开始则当前的tt是有值的
for(int i = 0; i < n; i++){
if(hh <= tt && i-k+1 > q[hh]) hh++;//判断队头是否该滑出窗口
while(hh <= tt && a[q[tt]] >= a[i]) tt--;
q[++tt] = i;
if(i >= k-1)cout << a[q[hh]] << " ";
}
cout << '\n';
hh = 0, tt = -1;
for(int i = 0; i < n; i++){
if(hh <= tt && i-k+1 > q[hh]) hh++;
while(hh <= tt && a[q[tt]] <= a[i]) tt--;
q[++tt] = i;
if(i >= k-1)cout << a[q[hh]] << " ";
}
cout << '\n';
return 0;
}

浙公网安备 33010602011771号