2133: 密室逃脱

来源:互联网 发布:王者荣耀助手网络错误 编辑:程序博客网 时间:2024/06/11 19:55

Description

XOR在玩密室逃脱,在某一关中,桌上有一个一张纸,上面写着“请根据所给例子求解答案从而获得密码”,下面写了几个字符串“01 10 11”,而答案为“6”,聪明的XOR立马就知道了这是给出一些二进制数字S,求存在多少对有序二元组(i,j)使得S[i]^S[j]<S[i],现在还有T组数据,每组是n个长度为m的二进制数字,聪明的XOR立马开始动手求解答案。

 

Input

第一行一个整数T,表示数据组数。

对于每组数据,首先读入两个整数n,m(n*m<=1000000),接下来为n行,每行为一个长度为m的01串,表示一个二进制数字

 

Output

对于每个数据,输出一个整数x,表示二元组数目

 

Sample Input

1
3 2
01
10
11

Sample Output

6

异或,相同为0,不同为1

s[ j ]首位1所在的位置n,s[ i ]首位1所在位置m

所以要求s[i]^s[j]<s[i]就表示n,m相同或者s[ i ] 的n位置也是1;

#include<bits/stdc++.h>using namespace std;int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n,m;        scanf("%d%d\n",&n,&m);        long long int a[m];//存首位1所在位置        long long int b[m];//存不是第一个出现的1的位置        for(int i=0;i<m;i++)        {            a[i]=0;            b[i]=0;        }        for(int i=0;i<n;i++)        {            char z[m+3];            scanf("%s",z);            int t=0;            for(int j=0;j<m;j++)            {                if(z[j]=='1'&&t==0)                {                    a[j]++;                    t=1;                }                else if(z[j]=='1'&&t==1)                {                    b[j]++;                }            }        }        long long int s=0;        for(int i=0;i<m;i++)        {            s=s+(a[i])*(a[i]+b[i]);//a[i]*a[i]表示第1种情况,a[i]*b[i]表示第2种情况        }        printf("%lld\n",s);    }}

0 0
原创粉丝点击