2024.4.10

 1.美丽的区间 - 蓝桥云课 (lanqiao.cn) 


//快慢指针例题 
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+2;
typedef long long ll;
ll a[N];
int main(){
  int n,s;cin>>n>>s;
  for(int i=1;i<=s;i++)cin>>a[i];
  ll l=1,r=0;//i是左指针 j是右指针
  ll ans=n+1;
  ll sum=0;
  for(int i=1,j=0,sum=0;i<=n;i++){//左指针指向第一个数 而右指针指向第一个数的左边
    while(i>j||(j+1<=n&&sum<s)){j++;sum+=a[j];}//或者sum+=a[++j];
//如果区间不合法 或者 右指针还有移动空间并且不满足条件的时候移动右指针
    if(sum>=s)ans=1ll*min(ans,1ll*(j-i+1));//更新长度
    sum-=a[i];//左指针右移带来的影响
  }
  cout<<(ans==n+1?0:ans);
  return 0;
}

AcWing 1236. 递增三元组(蓝桥杯辅导课) - AcWing


//做法3:双指针
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+7;
int a[N],b[N],c[N];
signed main(){
	int n;cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++) scanf("%d", &a[i]);
    for(int i=1;i<=n;i++) scanf("%d", &b[i]);
    for(int i=1;i<=n;i++) scanf("%d", &c[i]);
	
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	sort(c+1,c+n+1);
	
	int l=1,r=1;//双指针 一个指针用于a数组 一个指针用于b数组 
	
	for(int i=1;i<=n;i++){
		while(a[l]<b[i]&&l<=n)l++;//l用于记录目前小于b[i]的数的个数
		//l肯定是越来越大的 //l肯定是越来越大的   l最后落在了第一个>=b[i]的数上 
		while(c[r]<=b[i]&&r<=n)r++;//r用来记录小于等于b[i]的数的个数
		//r最后落在了一个>b[i]的数上 
		ans+=(l-1)*(n-r+1);
	} 
	cout<<ans;
	return 0;
}

796. 子矩阵的和 - AcWing题库


#include <bits/stdc++.h>
using namespace std;
const int N=1007;
//二维前缀和:预处理要与a[i][j]相关联
//预处理:s[i][j]=s[i-1][j]+s[i][j-1]+a[i][j]-s[i-1][j-1]  -重复 
//实现:(x1,y1)以左上角 (x2,y2)为右上角
//实现:  s[x2[y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1][y2]      +重复
 
//一维差分: 预处理b[i]=a[i]-a[i-1]    b[i]改变后面的数都改 
//二维差分:
//预处理: 
//void insert(int x1,int y1,int x2,int y2){               +重复 
//b[x1][y1]+=c;
//b[x2+1][y1]-=c;
//b[x1][y2+1]-=c;
//b[x2][y2]+=c;
//实现:
//b[i[j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1]               -重复 
int a[N][N];
int pre[N][N];
int main(){
	int n,m,q;cin>>n>>m>>q;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		pre[i][j]=pre[i-1][j]+pre[i][j-1]+a[i][j]-pre[i-1][j-1];
		}
	}
	while(q--){
		int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;
		cout<<pre[x2][y2]-pre[x1-1][y2]-pre[x2][y1-1]+pre[x1-1][y1-1]<<'\n';
	}
	return 0;
}

 154. 滑动窗口 - AcWing题库


#include <iostream>
using namespace std;
const int N = 1000010;
int a[N], q[N], hh=1, tt = 0;
//q[i]用来存下标
//一般hh设在第一个元素 tt设在hh的前面一位
void getMinWindow(int n, int k) {
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        //右端点是i 长度是k 左端点是i-k+1>q[hh]的时候
        while(tt>=hh&&i-k+1>q[hh])hh++;//队首元素出队
        while (hh <= tt && a[i] <= a[q[tt]]) --tt;//维护队首元素是最小值
        q[++tt] = i;
        if (i >= k) cout << a[q[hh]] << " ";//形成了一个窗口
    }
    cout << '\n';
}
 
void getMaxWindow(int n, int k) {
    hh = 1; tt = 0;
    for (int i = 1; i <= n; ++i) {
        while(tt>=hh&&i-k+1>q[hh])hh++;
        while (hh <= tt && a[i] >= a[q[tt]]) --tt;
        q[++tt] = i;
        if (i >= k) cout << a[q[hh]] << " ";
    }
}
 
int main() {
    int n, k;
    cin >> n >> k;
    getMinWindow(n, k);
    getMaxWindow(n, k);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值