题目链接:http://lx.lanqiao.cn/problem.page?gpid=T519
先看一些基本的位运算:
学位运算为以后状压,压位做下铺垫吧。
题目描述:
样例输入
3 2 //3个同学 2幅画,判断完全相反的对数
1 0
0 1
1 0
样例输出
2
样例说明
同学1和同学2的答案完全相反;
同学2和同学3的答案完全相反;
所以答案是2。
总的来说就是res[]保存20位所有的状态,用全1状态异或同学状态,找到异或后状态的同学总数,即全相反数,再除以2,就是全相反对数。
#include<bits/stdc++.h>
using namespace std;
int res[1<<20],z[50010];//创建能表示20种情况的数组
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int tmp;scanf("%d",&tmp);
z[i]=(z[i]<<1)+tmp;
}
res[z[i]]++;
}
int q =(1<<m)-1,ans=0;//全1的情况
for(int i=0;i<n;i++){
int tmp=q^z[i];//与全1异或的学生状态
ans+=res[tmp];//此状态下有几个同学
}
cout<<ans/2;
return 0;
}