atcoder 439D
原文链接:https://www.cnblogs.com/Time25/p/19778231.html
题目大意
(https://atcoder.jp/contests/abc439/tasks/abc439_d)
给你一个数组,要求求出满足要求的(Ai,Aj,Ak)要求是
三个数字之比是7:5:3
这三个数字中j不可以是中间那个数字,要么是最大,要么是最小
分析
直接去算的话,未免有点困难,所谓正难则反,我们可以先把所有的都求出来,然后减去不满足要求的,剩下的就是我们要的
1.核心函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25int cal(vector<int>&v7,vector<int>&v5,vector<int>&v3){
int res=v7.size();
res*=v5.size();
res*=v3.size();
vector<pair<int,int>>vp;
for(auto&nx:v7)vp.pb({nx,7});
for(auto&nx:v5)vp.pb({nx,5});
for(auto&nx:v3)vp.pb({nx,3});
sort(all(vp));
int l7=0,r7=v7.size();
int l3=0,r3=v3.size();
for(int i=0;i<vp.size();i++){
if(vp[i].second==5){
res-=l7*r3;
res-=l3*r7;
}else if(vp[i].second==3){
l3++;
r3--;
}else if(vp[i].second==7){
l7++;
r7--;
}
}
return res;
}
就是把以x为基地(7x,5x,3x)的所有可能乘起来这个就是总的,然后按照下标给这些排序,然后计算出在以x为基底的的情况下,有多少事j为中间那个数字的情况,也就是5在中间,7在头3在尾巴,和3在头7在尾
把这些减去就好了
完整code
1 |
|
小疑惑1
2
3
4if(a[i]%7==0){
mp[{a[i]/7,7}].pb(i);
s.insert(a[i]/7);
}
这个的set里存的是什么呢?其实就是上面说的基地,把这个数组中所有基底的情况都考虑一遍,每个基底都按照上面那个方法计算一次,再把总的加起来,就是我们想要的答案了
为什么存的是除以7的?为什么不是除以5或者除以3呢,其实都是一样的,因为,如果一个基底7在这个数组中是找不到的话,那就没必要去计算了
那要是这个基底x7在数组中有,但是它乘以5或者3在数组中没有呢?我们在计算的时候,就是1
2
3int res=v7.size();
res*=v5.size();
res*=v3.size();
如果有一个没有的话,乘的就是0,那么也就不用担心会影响我我们答案的结果了
