首页 > 其他分享 >蓝桥杯 递增三元组

蓝桥杯 递增三元组

时间:2024-03-16 18:32:34浏览次数:30  
标签:java int 递增 三元组 蓝桥 ++ static import new

Problem: 蓝桥杯 递增三元组

文章目录

思路

这是一个关于数组的问题,我们需要找到一个递增的三元组。这个三元组由三个数组中的元素组成,每个数组提供一个元素,并且这三个元素满足递增的关系。

解题方法

我们可以使用三种方法来解决这个问题:前缀和,二分查找和双指针。
1、前缀和:我们首先对数组a和c进行计数,然后计算出前缀和。然后,我们遍历数组b,对于每一个元素bi,我们找到数组a中小于bi的元素数量和数组c中大于bi的元素数量,然后将这两个数量相乘,累加到结果中。
2、二分查找:我们首先对数组a和c进行排序。然后,我们遍历数组b,对于每一个元素bi,我们使用二分查找在数组a中找到小于bi的最大元素的位置,和在数组c中找到大于bi的最小元素的位置,然后将这两个位置相乘,累加到结果中。
3、双指针:我们首先对数组a,b和c进行排序。然后,我们使用两个指针,一个指向数组a的开始,一个指向数组c的开始。我们遍历数组b,对于每一个元素bi,我们移动数组a的指针,直到找到一个大于或等于bi的元素,然后移动数组c的指针,直到找到一个大于bi的元素,然后将这两个位置相乘,累加到结果中。

复杂度

时间复杂度:

对于前缀和和双指针方法,时间复杂度为 O ( n ) O(n) O(n)。对于二分查找方法,时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。

空间复杂度:

对于所有的方法,空间复杂度都为 O ( n ) O(n) O(n)。

前缀和Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int MAXN = (int) (1e5 + 10);
	static int[] a = new int[MAXN];
	static int[] b = new int[MAXN];
	static int[] c = new int[MAXN];
	static int[] as = new int[MAXN];
	static int[] cs = new int[MAXN];
	static int n;

	public static void main(String[] args) throws IOException {
		n = nextInt();
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}

		for (int i = 0; i < n; i++) {
			b[i] = nextInt();
		}

		for (int i = 0; i < n; i++) {
			c[i] = nextInt();
		}
		for (int i = 0; i < n; i++) {
			as[a[i]]++;
			cs[c[i]]++;
		}

		// 计算出前缀和
		for (int i = 1; i < MAXN; i++) {
			as[i] += as[i - 1];
			cs[i] += cs[i - 1];
		}

		long res = 0;
		// 枚举枚举每一个bi
		for (int i = 0; i < n; i++) {
			if (b[i] == 0) {
				continue;
			}
			res += (long) as[b[i] - 1] * (long) (cs[MAXN - 1] - cs[b[i]]);
		}

		out.println(res);
		out.flush();

	}

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

二分Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int MAXN = (int) (1e5 + 10);
	static int[] a = new int[MAXN];
	static int[] b = new int[MAXN];
	static int[] c = new int[MAXN];
	static int n;

	public static void main(String[] args) throws IOException {
		n = nextInt();
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}

		for (int i = 0; i < n; i++) {
			b[i] = nextInt();
		}

		for (int i = 0; i < n; i++) {
			c[i] = nextInt();
		}
		Arrays.sort(a, 0, n);
		Arrays.sort(c, 0, n);

		// 二分查找 小于bi最右边的数字 目的尽可能多
		// 大于bi最左边的数字 目的是让数字尽可能多
		long res = 0;
		for (int i = 0; i < n; i++) {
			int left = getA(0, n - 1, b[i]);
			int right = getB(0, n - 1, b[i]);
			res += (long) (left + 1) * (n - right);
		}
		out.println(res);
		out.flush();

	}

	private static int getA(int l, int r, int x) {
		// TODO Auto-generated method stub
		while (l < r) {
			int mid = (l + r + 1) / 2;
			if (a[mid] < x) {
				l = mid;
			} else {
				r = mid - 1;
			}
		}
		return a[l] < x ? l : -1;
	}

	private static int getB(int l, int r, int x) {
		// TODO Auto-generated method stub
		while (l < r) {
			int mid = (l + r) / 2;
			if (c[mid] > x) {
				r = mid;
			} else {
				l = mid + 1;
			}
		}
		return c[r] > x ? r : n;
	}

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

双指针Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int MAXN = (int) (1e5 + 10);
	static int[] a = new int[MAXN];
	static int[] b = new int[MAXN];
	static int[] c = new int[MAXN];
	static int n;

	public static void main(String[] args) throws IOException {
		n = nextInt();
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		for (int i = 0; i < n; i++) {
			b[i] = nextInt();
		}
		for (int i = 0; i < n; i++) {
			c[i] = nextInt();
		}

		Arrays.sort(a, 0, n);
		Arrays.sort(b, 0, n);
		Arrays.sort(c, 0, n);

		// 使用双指针算法
		long res = 0;
		for (int i = 0, ai = 0, ci = 0; i < n; i++) {
			while (ai < n && a[ai] < b[i]) {
				ai++;
			}
			while (ci < n && c[ci] <= b[i]) {
				ci++;
			}
			res += (long) ai * (n - ci);
		}

		out.println(res);
		out.flush();

	}

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

标签:java,int,递增,三元组,蓝桥,++,static,import,new
From: https://blog.csdn.net/m0_73939789/article/details/136689278

相关文章

  • [蓝桥杯 2017 国 C] 合根植物(P8654)
    #include<bits/stdc++.h>#defineendl'\n'usingll=longlong;typedefunsignedlonglongull;usingnamespacestd;voidGordenGhost();intn,m;map<int,int>fa;intfindB(intx){if(fa[x]==x)returnx;returnfa[x]=findB(......
  • 贪心算法(算法竞赛、蓝桥杯)--均分纸牌
    1、B站视频链接:A30贪心算法P1031[NOIP2002提高组]均分纸牌_哔哩哔哩_bilibili题目链接:[NOIP2002提高组]均分纸牌-洛谷#include<bits/stdc++.h>usingnamespacestd;intn,a[101],av,cnt;intmain(){ scanf("%d",&n); for(inti=1;i<=n;i++){ scanf("%d&quo......
  • 贪心算法(算法竞赛、蓝桥杯)--奶牛晒衣服
    1、B站视频链接:A28贪心算法P1843奶牛晒衣服_哔哩哔哩_bilibili题目链接:奶牛晒衣服-洛谷#include<bits/stdc++.h>usingnamespacestd;priority_queue<int>q;//用大根堆维护湿度的最大值intn,a,b;inttim,maxn;intmain(){ scanf("%d%d%d",&n,&a,&b); for......
  • 蓝桥杯刷题(七)
    [蓝桥杯2023省A]平方差题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示【样例说明】【评测用例规模与约定】代码题目描述输入格式输出格式样例#1样例输入#1样例输出#1样例#2样例输入#2样例输出#2提示代码题目描述输入格式输出格式样例#1样......
  • 第八届蓝桥杯省赛 分巧克力(二分)
    题目描述:  思路:给出N个长方形的长和宽,可以分别看长能被分成多少块,宽能被分为多少块,也就是(h/mid)*(w/mid),使其大于等于K所以我们可以通过二分去找,最大的边长是多少AC代码: #include<iostream>usingnamespacestd;typedeflonglongLL;constintN=1......
  • 蓝桥杯 3.14 三国问题
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e5+100;inta1[N],b1[N],c1[N],w[N];longlongn,m;longlongs;intsheng(inta[],intb[],intc[]){memset(w,0,sizeof(w));//数组初始化为0,只有在定义时才可以用{0}//cout<<'$';for(int......
  • 14届蓝桥杯省赛E题——颜色平衡树
    一、题目描述二、题目分析设颜色平衡树的节点有n个,颜色种类为p种,每种颜色的出现次数均为q,则n=p*q。换句话说,如果一棵树的出现次数最多的颜色们的出现次数之和等于该树的节点个数,那么这棵树是颜色平衡树。为了降低遍历次数,采用树上启发式合并,定义树中节点最多的子树为重子树......
  • P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值
    题目描述给定一棵包含N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是​,如下图所示: 现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。注:根的深度是 1......
  • 备战蓝桥杯Day27 - 省赛真题-2023
    题目描述大佬代码importosimportsysdeffind(n):k=0fornuminrange(12345678,98765433):str1=["2","0","2","3"]forxinstr(num):ifxinstr1:ifstr1[0]==x......
  • C++ | 蓝桥题库区间或(位运算)
    一开始看题解很晕,这里采用前缀和方式的思想是:按位贡献,将答案分成32份(1e9最多32位二进制数)这样才有的prefix[32][N]前缀和数组,求的是第i位数第w位上的和。(1<<w)1左移w位相当于2的w次方,prefix[w][r]-prefix[w][l-1]相当于[l,r]这段距离上有1就让ans加上1,没有就不加。#inc......