题目链接: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);
}