题目链接:1305

思路:

首先   要看出来 (A[ i ] + A[ j ] ) / ( A[ i ] * A [ j ] )  其实就是 (  1 / A[ i ] + 1 / A [ j ] )

然后又要向下取整  所以对于   1 / A[ i ]    如果分母是1  结果等于1   如果分母是2 结果是0.5  剩下的 结果都小于0.5

所以(  1 / A[ i ] + 1 / A [ j ] ) 要么是 1+1=2  要么是0.5+0.5=1   要么就是  0

然后我们再观察题目上的运算规则

我们把  取整【 ( 1 / A[ i ] + 1 / A [ j ] )】运算   称为 O 运算 

这个规则其实是 数组中的每一个数字都和其他每一个数字(除了他本身)做了  O  运算。

那么  如果A[ i ]是1  和同样是1的数字 做 O 运算  结果是2   和其他非1的数做O运算 结果是1

        如果A[ i ]是2 只有和其他同样是2的数做 O 运算  结果才是1  其余的数 结果都是0

所以 最终的结果其实等于=

所有的1两两结合的情况数量*2   +所有的1和其他非1的数结合的情况数量 +  所有的2两两结合的情况数量

排列组合   先统计出1的数量=c1   2的数量=c2   其他的数的数量=c3

从c1里面选择两个相结合  有 c1*(c1-1)/2  这么多种  再  * 2     最终= c1*(c1-1)

从c2里面选两个相结合   情况有c2*(c2-1)/2这么多    再 * 1   最终=c2*(c2-1)/2

c1和其他数字结合    情况有 c1*(c2 + c3)种

ans= c1*(c1-1)+ c2*(c2-1)/2 + c1*(c2 + c3)

代码

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
int main(){
    int n,x;
    scanf("%d",&n);
    ll c1=0,c2=0,c3=0;
    for(int i=0;i<n;i++){
        scanf("%d",&x);
        if(x==1)c1++;
        else if(x==2)c2++;
        else c3++;
    }
    ll sum;
    sum=c1*(c1-1)+c1*(c3+c2)+c2*(c2-1)/2;
    printf("%lld\n",sum);
}