递增三元组 蓝桥杯2018年试题F

目录

 问题描述

问题分析

算法优化

代码

运行结果


 问题描述

A = [A1, A2, … AN],
B = [B1, B2, … BN],
C = [C1, C2, … CN],
请你统计有多少个三元组(i, j, k) 满足:

1 <= i, j, k <= N
Ai < Bj < Ck
输入
第一行包含一个整数N。
第二行包含N个整数A1, A2, … AN。
第三行包含N个整数B1, B2, … BN。
第四行包含N个整数C1, C2, … CN。
1 <= N <= 100000 0 <= Ai, Bi, Ci <= 100000

输出
一个整数表示答案

样例输入
3
1 1 1
2 2 2
3 3 3
样例输出
27

问题分析

对于本题可以采取暴力求解的方式,使用三重嵌套循环,逐个枚举,时间复杂度会达到

O(n^3),N达到100000时会超时严重:

#include<bits/stdc++.h>
using namespace std;
const  int N=1000000;
int A[N],B[N],C[N];
int main()
{   int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>A[i];
    for(int i=0;i<n;i++)cin>>B[i];
	for(int i=0;i<n;i++)cin>>C[i];
	int count=0;
	for(int i=0;i<n;i++)
	 for(int j=0;j<n;j++)
	   for(int k=0;k<n;k++)
	      if(A[i]<B[j]&&B[j]<=C[k])
	          count++;
	cout<<count;

    return 0;
	
}

算法优化

对算法进行改进将A[i]和B[j]大小比较和B[j]和C[k]的大小比较分开来比较,进行统计,再将统计的结果相乘即可,counta为A中小于B[i]的个数;countb为B中小于C[i]的个数,对枚举次序进行调整,时间复杂度就会降低为O(n^2):

for(int i=0;i<n;i++){
	
	 for(int j=0;j<n;j++)
	    {
	    	if(A[i]<B[j]) counta++;
	    	if(B[i]<C[j]) countb++;
		}
	 num+=counta*countb;
	counta=0;
	countb=0; 
}

仔细分析,统计一个数比一个序列大的数据数目,本质上可以转换成查找算法,最高效的查找算法就是二分法,首先要对这三个数组进行排序。

排序后可进行二分查找,A中小于B[i]中最大的一个A[i],求出数组a中小于B[i]的个数wa,当A[j]<B[i]时,A[0]~A[j]一定小于B[i],以此类推C中第一个比B[i]大的数,求出数组C中小于B[i]的数wc,只要找到第一个比B[i]大的数,那么它之后的数也比B[i]大。wa*wc就是递增三元组的总个数。

代码

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;

int a[100000],b[100000],c[100000];
//找出数组A中小于B[i]的最大数的下标
int small(int n,int a[],int key)
{   int left=1,right=n;
	while(left<right){
	
	 int mid=left+right+1/2;
	 if(a[mid]<key)left=mid;
	 else right=mid -1;
}
  
    return left;

 } 
//找出数组C中第一个大于B[i]的数 
int big(int n,int c[],int key)
{   int left=1,right=n;
	while(left<right){
	
	 int mid=(left+right)/2;
	 if(c[mid]>key) right=mid;
	 else left=mid +1;
	 }
	 
 
    return left;

 } 
 




int main()
{   int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<=n;i++) cin>>c[i];
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
    sort(c+1,c+n+1);//排序
    LL count=0;
	
	for(int i=1;i<=n;i++)
	{
	  int key=b[i];
	  LL wa=small(n,a,key);
	  LL wc=big(n,c,key);
	  
	  if(a[wa]<key&&c[wc]>key)  count +=(wa-1)*(n+1-wc);
	     
	}
	
    cout<<count<<endl;
    return 0;
	
}

运行结果

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯Python国赛试题是指蓝桥杯竞赛中的Python编程试题。根据提供的引用内容,我无法直接回答你具体的试题内容。但是我可以告诉你蓝桥杯Python国赛试题的一般情况。 蓝桥杯Python国赛试题通常包括编程题和选择题两部分。编程题需要你使用Python语言完成特定的编程任务,例如找到一组数字中的最大值、拼接字符串等。选择题则需要你对Python语法和常见的编程知识进行理解和运用,例如字符串的切片和格式化输出。 蓝桥杯Python国赛试题的难度会根据级分级别,从初级到高级依次递增试题会考察你的编程思维能力、代码实现能力以及对Python语言的掌握程度。 总结起来,蓝桥杯Python国赛试题旨在考察参赛者对Python语言的理解和应用能力。通过解答这些试题,可以提升自己的编程技巧和解决问题的能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [2021蓝桥杯赛题【Python】](https://blog.csdn.net/weixin_47126666/article/details/123630739)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [十二届蓝桥杯Python组国赛试题](https://blog.csdn.net/lybc2019/article/details/124669487)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值