顺序三元组问题(计蒜客)

  • 问题描述
  • https://nanti.jisuanke.com/t/T1269

     

  • 给定一个长度为 N 的数组 A=[A1​,A2​,...AN​],已知其中每个元素 Ai​ 的值都只可能是 1,2 或者3。
  • 请求出有多少下标三元组 (i,j,k) 满足 1≤i<j<k≤N 且 Ai​<Aj​<Ak​。
  • 输入格式
  • 第一行包含一个整数 N;
  • 第二行包含 N 个整数 A1​,A2​,...AN​。(1≤Ai​≤3,1≤N≤100000)。
  • 输出格式
  • 一个整数表示答案。
  • 样例输入
  • 6
  • 1 3 2 1 2 3
  • 样例输出
  • 3
  • 代码
    //注销的这部分代码会出错,因为n可以取到10^5,俩层for循环会超时,所以要另辟蹊径
    /*#include <iostream>
    #include <vector>
    using namespace std;
    int cheak(int* arr, int start, int len) {//从start位置开始,数字3的个数
    	int sum = 0;
    	for (int i = start; i < len; i++)
    		if (arr[i] == 3) sum++;
    	return sum;
    }
    int main() {
    	int n;//n个数
    	cin >> n;
    	int ans = 0;//结果
    	//vector <int> arr(n);
    	int arr[100000] = { 0 };
    	//const int len = arr.size();
    	for (int i = 0; i < n; i++)
    		cin >> arr[i];
    	if (n < 3) {//数组小于3
    		cout << 0 << endl;
    		return 0;
    	}
    	int flag1 = 0, flag2 = 0;//1 2出现的标志
    
    	for (int j = 0; j < n; j++) {
    		if (cheak(arr, j + 1, n) == 0) {
    			cout << ans << endl;
    			return 0;
    		}
    		if (arr[j] == 1) flag1 = 1;//出现1
    		if (flag1 == 1) {
    			for (int i = j; i < n; i++) {
    				if (cheak(arr, j + 1, n) == 0) {
    					cout << ans << endl;
    					return 0;
    				}
    				if (arr[i] == 2) flag2 = 1;//出现2
    				if (flag2 == 1) {//统计后面3的个数
    					ans = ans + cheak(arr, i + 1, n);
    					flag2 = 0;
    				}
    				//if (cheak(arr, j+1, n) == 0) break;
    			}
    			flag1 = 0;
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }*/
    #include <iostream>
    #include <vector>
    using namespace std;
    int arr[100005];
    long long sum[100005];
    int main() {
    	int n;//n个数
    	cin >> n;
    	for (int i = 0; i < n; i++)
    		cin >> arr[i];
    
    	if (n < 3) {//数组小于3
    		cout << 0 << endl;
    		return 0;
    	}
        
    	long num = 0;
    	for (int i = 0; i < n; i++) {
    		if (arr[i] == 1)//统计1的数目,也可以说是1的前缀和
    			++num;
    			sum[i] = num;
    	}
    	long su1 = 0;
    	for (int i = 0; i < n; i++) {
    		if (arr[i] == 1) su1 = sum[i];
    		if (arr[i] == 2 ) sum[i] = su1;//统计每个2前面有多少个1
                                           //也可以说是(1,2)的前缀和
    	}
        
    	long su2 = 0;	
    	for (int i = 0; i < n; i++) {
    		if (arr[i] == 2) su2 += sum[i];
    		if (arr[i] == 3) sum[i] =su2;//统计每个3前面有多少个(1,2)
                                         //也可以说是(1,2,3)的前缀和
    	}
        
        long ans = 0;  //结果
    	for (int i = 0; i < n; i++) {
    		if (arr[i] == 3) ans += sum[i];
    	}
    	cout << ans << endl;
    	return 0;
    }

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三元组顺序表加法是指在两个三元组顺序表之间进行元素相加的操作。假设有两个三元组顺序表A和B,它们的存储结构为三个一维数组data、row、col。其中data数组存储三元组中的元素值,row数组存储相应元素在矩阵中的行号,col数组存储相应元素在矩阵中的列号。 实现三元组顺序表的加法,首先要判断两个三元组顺序表的行数和列数是否相等,只有相等时才能进行加法操作。然后按照以下步骤进行: 1. 创建一个新的三元组顺序表C,用于存储两个三元组顺序表相加的结果。 2. 分别设置两个指针pA和pB,分别指向A和B的data数组的起始位置。 3. 利用循环遍历data数组,将A和B的对应位置的元素相加,并将相加的结果存储到C的data数组中。 4. 在遍历过程中,如果pA所指示的元素的行号小于pB所指示的元素的行号,将pA向后移动一位;如果行号相等,则比较列号,如果pA所指示的元素的列号小于pB所指示的元素的列号,则将pA向后移动一位;如果列号相等,则将两个元素的值相加,并将相加的结果存储到C的data数组中。 5. 在每次循环中,将C的row数组和col数组的对应位置分别更新为pA所指示元素的行号和列号。 6. 循环结束后,C的data数组中存储的就是A和B相加的结果,C的row数组和col数组就是相应元素在矩阵中的行号和列号。 最后,返回C作为两个三元组顺序表相加的结果。这样就实现了三元组顺序表的加法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值