作者:lmaster | 来源:互联网 | 2024-10-25 13:00
这个题手动压位非常麻烦,因为对于同一块,后加的数比先加的数小,所以判断最后一位的时候需要定位到最后一块最小的数,而且在找元的时候还不能找到这个位置注意块的总数每个是30个不要存错,
这个题手动压位非常麻烦,因为对于同一块,后加的数比先加的数小,所以判断最后一位的时候需要定位到最后一块最小的数,而且在找元的时候还不能找到这个位置
注意块的总数每个是30个不要存错,
码:
#include
#include
#include
using namespace std;
int n,m,i,j,k,l,cnt,ans[2005],a[2005][2005],p,er[55];
char ch;
bool y[4005];
int gauss()
{
int o=0;
for(i=1;i<=m;i++)
{
for(j=1;j<=cnt;j++)
{
bool ky=0;
for(p=0;p<=30;p++)
if((a[i][j]&er[p])){if(j==cnt&&p==0)continue;ky=1;break; }
if(ky)break;
}
if(j==cnt+1)
{
o++;
continue;
}
for(k=1;k<=m;k++)
{
if(k==i||(a[k][j]&er[p])==0)continue;
for(l=1;l<=cnt;l++)
{
a[k][l]^=a[i][l];
}
}
if(i-o==n) break;
}
for(k=1;k<=i;k++)
{
for(j=1;j<=cnt;j++)
for(l=30;l>=0;l--)
if(a[k][j]&er[l]){ if(j==cnt&&l==0)continue; ans[(j-1)*31+(30-l)]=(a[k][cnt]&1);y[(j-1)*31+(30-l)]=1;break; }
}
return i;
}
int main()
{
er[0]=1;
for(i=1;i<=30;i++)
er[i]=er[i-1]*2;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
cnt=0;
for(j=1;j<=n+1;j++)
{ if((j-1)%30==0)++cnt;
scanf("%c",&ch);
while(ch!='0'&&ch!='1')scanf("%c",&ch);
a[i][cnt]=a[i][cnt]*2+(ch-'0');
}
}
int lin=gauss();
if(lin