zoukankan      html  css  js  c++  java
  • [SDOI2010]外星千足虫

    传送门


    强化一下高斯消元。


    学了线代以后就是不一样,这题就是线性方程组的水题嘛。

    题目已经将异或方程组直接告诉你了,然后问你最少需要几个方程(按顺序)才能有唯一解(保证有解)。

    因为要按顺序选取方程,所以只要正常的解(m)个方程就好了。高斯消元的时候,对于第(i)列,我们要找最靠前的一行(x),满足这一行的第(i)列为(1)。如果没有,就说明有无穷多解,否则记录下来(x),表示至少需要到第(x)个方程,第(i)个未知数才能确定。那么最后需要的最少方程数,就是( extrm{max} { x }).

    因为(O(n^2m))会超时,所以用bitset优化,就过了。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<assert.h>
    #include<ctime>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 1e3 + 5;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    char s[maxn];
    int n, m;
    bitset<maxn> f[maxn << 1];
    
    In int Gauss()
    {
    	int ret = 0;
    	for(int i = 1; i <= m; ++i)
    	{
    		int pos = i;
    		while(pos <= m && !f[pos][i]) ++pos;
    		if(pos > m) return -1;			//无穷解 
    		ret = max(ret, pos);
    		if(pos ^ i) swap(f[i], f[pos]);
    		for(int j = i + 1; j <= m; ++j) if(f[j][i]) f[j] ^= f[i];
    		if(i == n) break;				//已经可以确定唯一解了 
    	}
    	for(int i = n; i; --i)
    		for(int j = i - 1; j; --j) if(f[j][i]) f[j] ^= f[i];	//回带 
    	return ret;
    }
    
    int main()
    {
    	n = read(), m = read();
    	for(int i = 1, x; i <= m; ++i)
    	{
    		scanf("%s%d", s + 1, &x);
    		for(int j = 1; j <= n; ++j) f[i][j] = s[j] == '1';
    		f[i][n + 1] = x;
    	}
    	int ans = Gauss();
    	if(ans == -1) puts("Cannot Determine");
    	else
    	{
    		write(ans), enter;
    		for(int i = 1; i <= n; ++i) puts(f[i][n + 1] ? "?y7M#" : "Earth");
    	}
    	return 0;
    }
    
  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/mrclr/p/15100897.html
Copyright © 2011-2022 走看看