zoukankan      html  css  js  c++  java
  • UVA 11542 高斯消元

    从数组中选择几个数,要求他们的乘积可以开平方,问有多少种方案。

    先将单个数拆分成质因子,对于这个数而言,那些指数为奇数的质因子会使这个数无法被开平方。

    所以我们需要选择一个对应质因子指数为奇数的元素,将他们两个放在一个方案中,但是又有可能会引入其他的质因子。

    这样就变成了求解行列式中自由变元的数量问题。

    将数组转换成行列式,利用高斯消元求解。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    bool pri[505];
    int a[501][501];
    int max_;
    int t, n;
    long long x;
    vector<int>V;
    
    void Prime(){
        memset(pri,1,sizeof(pri));
        pri[0] = pri[1] = 0;
        for(int i=2;i<501;i++)if(pri[i]){
            V.push_back(i);//对素数离散一下 优化一下
            for(int j=i<<1;j<501;j+=i)
                pri[i] = 0;
        }
    }
    void init(){
        memset(a,0,sizeof(a));
        max_ = 0;
    }
    int gauss(){// 高斯消元
        int i = 0, j = 0;
        while(i<=max_ && j<n){
            int k = i;
            for(;k<=max_;k++)
                if(a[k][j])break;
            if(k != max_ + 1){
                for(int l=0;l<n;l++){
                    // 第j个等式的 k位上为 1
                    // 将第 k 行与第 i 行 进行 行交换
                    swap(a[i][l],a[k][l]);
                }
                for(int k=i+1;k<=max_;k++){
                    if(a[k][j]){
                        for(int l=j;l<n;l++)
                            a[k][l] ^= a[i][l];// 这里是优化后的式子
                    }
                }
                i++;
            }
            j++;
        }
        return n-i;
    }
    int main(){
        Prime();
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%lld",&x);
                for(int j=0;j<V.size() && V[j]<= x;j++){
                    while(x%V[j] == 0){
                        a[j][i] ^= 1;
                        // 若 质因子的指数为偶数 则行列式对应位上为 0
                        //    奇数 为 1
                        max_ = max(max_, j);
                        // 记录一下最大值, 优化
                        x /= V[j];
                    }
                }
            }
            printf("%lld
    ",(1ll<<gauss())-1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    unity代码加密for Android,mono编译
    php __invoke 和 __autoload
    VC只运行一个程序实例
    VC单文档对话框添加托盘图标
    技术文档应该怎么写
    项目管理学习
    cannot download, /home/azhukov/go is a GOROOT, not a GOPATH
    Go语言学习
    appium键盘事件
    appium-doctor
  • 原文地址:https://www.cnblogs.com/kongbb/p/10686669.html
Copyright © 2011-2022 走看看