- 问题描述
- 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; }
顺序三元组问题(计蒜客)
最新推荐文章于 2023-12-27 11:35:34 发布