一开始傻傻的超原始暴力,只拿了70分
后来参考了别人的思路用位运算解出来了
思路:
①两个二进制数若完全相反,异或结果为全一,如10010和01101异或结果是11111
②将二进制转化为十进制
③用一个数组记录下每个数出现的次数
④只需要遍历每个数a,将其与全1异或,得到的结果b的个数就是与a完全相反的个数
我的代码:
#include<bits/stdc++.h>
using namespace std;
int num[10000000]; //数组必须开这么大,少一个零都不行
int main(){
int n, m, tmp=0, t, maxx, ans=0;
cin>>n>>m;
maxx = (1<<m) - 1; //获得全1二进制数
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin>>t;
tmp = (tmp<<1) + t; //将二进制转化为十进制
}
ans += num[tmp^maxx]; //每个同学和前面的同学比较看有没有全反的,所以后面不用除以2
num[tmp]++;
tmp = 0;
}
cout<<ans;
}