双指针

https://www.luogu.com.cn/problem/list?tag=345

洛谷题目

1 A+B

#include <bits/stdc++.h>
#define ll long long

using namespace std;

const int N = 2e5 + 10;
int n , c;
int a[N];

int main () 
{
	cin >> n >> c;
	for(int i = 1 ; i <= n ; i ++) cin >> a[i];
	sort(a + 1 , a + 1 + n);
	int l = 1, r1 = 1 , r2 = 1;
	ll ans = 0;
	for(l = 1 ; l <= n ; l ++) {
		while(r1 <= n && a[r1] - a[l] <= c) r1 ++;
		while(r2 <= n && a[r2] - a[l] < c ) r2 ++;
		if(a[r2] - a[l] == c && a[r1 - 1] - a[l] == c && r1 - 1 >= 1) 	
			ans += r1 - r2;
	}
	cout << ans;
	return 0;
}

#include<bits/stdc++.h>
#define int long long
const int maxn=2e5+10;
int a[maxn];
using namespace std;
signed main()
	{
	int n,c;
	cin>>n>>c;
	for(int i=0; i<n; i++)
		{
		cin>>a[i];
		}
	sort(a,a+n);
	int sum=0;
	for(int i=0; i<n; i++)
		{
		int l=upper_bound(a,a+n,a[i]-c)-a;
		int r=lower_bound(a,a+n,a[i]-c)-a;
		sum+=l-r;
		}
	cout<<sum;
	}

2 连续整数和

#include<bits/stdc++.h>
#define int long long
const int maxn=2e6+10;
int a[maxn];
using namespace std;
signed main()
	{
	int n;
	cin>>n;
	int l=1;
	int r=1;
	int sum=0;
	while(l<=n)
		{
		sum=0;
		r=l;
		//在这里重置
		while(sum<n&&r<=n)
			{
			sum+=r;
			if(sum==n)
				{
				if(r-l>0)
					cout<<l<<" "<<r<<endl;
				break;
				}
			r++;
			}
		l++;
		
		}

	}

3 子矩阵和小于k的数量

https://www.luogu.com.cn/problem/P8783

二维指针

#include<bits/stdc++.h>
using namespace std;
long long n,m,k,a[510][510],sum[510][510],b[510];
long long l,r,now,ans;
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin>>a[i][j];
	for(int j=1;j<=m;j++)
		for(int i=1;i<=n;i++)
			sum[i][j]=sum[i-1][j]+a[i][j];
	for(int x=1;x<=n;x++)
		for(int y=x;y<=n;y++){
		//	cout<<x<<" "<<y<<":"<<endl;
			for(int j=1;j<=m;j++)
				b[j]=sum[y][j]-sum[x-1][j];
			//双指针
			l=1;r=1;now=0;
			for(r=1;r<=m;r++){
				now+=b[r];
				if(now<=k){
				//	cout<<l<<" "<<r<<" "<<now<<endl; 
					ans+=r-l+1;
				}
				else{
					while(now>k){
						now-=b[l];
						l++;
					}
					ans+=r-l+1;
				}
			}
		//	cout<<"-------"<<endl;
		}
	cout<<ans<<endl;
	return 0;
}

4 整数拼接小于k

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int MAXN = 100010;

ll N, K, P, ANS;
ll A[MAXN];

inline ll connect(ll a, ll b){
    return stoll(to_string(a) + to_string(b));
	//stoll字符串转化为数字,to_string将数字转化为字符串
}

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> N >> K;
    for (int i = 1; i <= N; ++i) cin >> A[i];
    sort(A + 1, A + N + 1);
    P = N;
    for (int i = 1; i <= N; ++i){
        while (P > 0 && connect(A[P], A[i]) > K) --P;
        //为啥没考虑反着拼接和p==i的情况,下标相同的数不进行拼接
		//因为是从小到大排序,然后从最大的开始,更小的a都不能拼接b使小于K,那比a大的a2肯定也不可能,所以
        ANS += P, ANS -= (P >= i);
		//当 P 大于或等于 i 时,从 ANS 中减去 1
    }
    cout << ANS << endl;
    return 0;
}
posted on 2024-09-02 19:36  Hoshino1  阅读(3)  评论(0编辑  收藏  举报