bzoj1923: [Sdoi2010]外星千足虫 高斯消元解抑或方程组

题目:点击打开链接

题解:每只虫为奇或偶数,所以高消解抑或方程组。

        我写的是用unsign int压32位的,注意位运算技巧的应用

        发现我高消一直写得很丑,可以直接在消元时得到对角线而不是上三角矩阵,

        不用再解方程求答案


#include<bits/stdc++.h>
using namespace std;
#define maxn 2010

unsigned int a[maxn][maxn];
int n,m,ans,t[maxn];
char ch[maxn];

void guass(){
	/*for (int i = 0 ; i < m ; i++){
	   	for (int j = 0 ; j <= n ; j++)
		   cout<<((a[i][j >> 5] >> (j & 31)) & 1);
		cout<<endl;
	}*/	
	for (int i = 0 ; i < n ; i++){
		int now = -1;
		for (int j = i ; j < m ; j++){
			if ( a[j][i >> 5] & (1 << (i & 31)) ){ now = j; break; } 
		}
		if ( now == -1 ){ ans = -1; return; }
		ans = max(ans,now + 1);	
		if ( now != i ) for (int j = 0 ; j <= n >> 5 ; j++) swap(a[now][j],a[i][j]);
		for (register int j = 0 ; j < m ; j++){ //从0开始消元即可,直接得到对角线
			if ( (a[j][i >> 5] & (1 << (i & 31))) && j != i ){
				for (register int k = 0 ; k <= n >> 5 ; k++)
					a[j][k] ^= a[i][k];
			}
		}
	}
}
void getans(){
	for (int i = n - 1 ;  i >= 0 ; i--){
		t[i] = (a[i][n >> 5] >> (n & 31)) & 1;
	//	for (int j = i + 1 ; j < n ; j++) t[i] ^= ((a[i][j >> 5] >> (j & 31)) & 1) * t[j]; 不用解方程了!
	}
	printf("%d\n",ans);
	for (int i = 0 ; i < n ; i++){
		if ( t[i] ) printf("?y7M#\n");
		else printf("Earth\n");
	}
}
int main(){
	freopen("input.txt","r",stdin);
	scanf("%d %d",&n,&m);
	for (int i = 0 ; i < m ; i++){
		scanf("%s",ch); int t; scanf("%d",&t);
		for (int j = 0 ; j < n ; j++){
			a[i][j >> 5] += (ch[j] == '1') << (j & 31);
		}
		a[i][n >> 5] += t << (n & 31);
	}
	guass();
	if ( ans == -1 ) return printf("Cannot Determine\n"),0;
	getans();
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值