zoukankan      html  css  js  c++  java
  • UVA11524构造系数数组+高斯消元解异或方程组

      1 /*UVA11524
      2 题目:给定n个数(n<=100),从中找出1或多个数,使他们的乘积是一个完全平方数
      3 分析:转化成数理模型是第一步,肯定要分解质因数,ps:题目给定不含大于500的素因子。
      4 第二选择的数字相同质因子个数之和必须是偶数,因为之奇偶性有关,可将奇数为1,偶数为0,这样约简。
      5 然后按照常理,应该找出所有的可能性(暴力的思想),因为n<=100,不可能用状态压缩的办法,所以用下面的方法,同时也是给自己一个拓展的思路
      6 高斯消元解异或方程组:
      7 假设n个数,设数组ch[i],表式选第i的数与否,那么,列出每个质因子的总个数方程,总个数模2为0即可,因为异或等同于模2加,故列异或方程。
      8 最后自由变量假设有k个,则说明2^k-1种方案
      9 解异或方程组的思路:
     10 1、构造系数数组(0,1)
     11 Mat[i][j]:第i个质因数的方程,第j个数字的因数分解后的个数
     12 2、解异或方程Mat(n,m)//要收录
     13 
     14 int solve(int n1,int m1) //解方程部分借鉴白书,要弄明白
     15 {
     16     int i=0,j=0;
     17     while(i<n1&&j<m1)
     18     {
     19         int r=i;
     20         for(int k=i; k<n1; k++)
     21             if (A[k][j])
     22             {
     23                 r=k;
     24                 break;
     25             }
     26         if (A[r][j])
     27         {
     28             if (r!=i) for(int k=0; k<=m1; k++) swap(A[r][k],A[i][k]);
     29             for(int u=i+1; u<n1; u++) if (A[u][j])
     30                     for(int k=i; k<=m1; k++) {A[u][k]^=A[i][k];}
     31             i++;
     32         }
     33         j++;
     34     }
     35     return i;
     36 }//返回的是确定解的个数
     37 */
     38 #include<iostream>
     39 #include<stdio.h>
     40 #include<string.h>
     41 #include<algorithm>
     42 #include<stdlib.h>
     43 #include<math.h>
     44 #include<queue>
     45 #include<vector>
     46 #include<map>
     47 //#define LL long long
     48 using namespace std;
     49 
     50 bool isprim[505];
     51 int cnt;
     52 int prim[505/2];
     53 void prime_calc()
     54 {
     55     cnt=0;
     56     memset(isprim,0,sizeof(isprim));
     57     for(int i=2; i<=500; i++)
     58     {
     59         if (!isprim[i])
     60         {
     61             prim[cnt++]=i;
     62             for(int j=2*i; j<=500; j+=i) isprim[j]=1;
     63         }
     64     }
     65 }
     66 
     67 int T,n;
     68 int A[505][505];
     69 
     70 int solve(int n1,int m1) //解方程部分借鉴白书,要弄明白
     71 {
     72     int i=0,j=0;
     73     while(i<n1&&j<m1)
     74     {
     75         int r=i;
     76         for(int k=i; k<n1; k++)
     77             if (A[k][j])
     78             {
     79                 r=k;
     80                 break;
     81             }
     82         if (A[r][j])
     83         {
     84             if (r!=i) for(int k=0; k<=m1; k++) swap(A[r][k],A[i][k]);
     85             for(int u=i+1; u<n1; u++) if (A[u][j])
     86                     for(int k=i; k<=m1; k++) A[u][k]^=A[i][k];
     87             i++;
     88         }
     89         j++;
     90     }
     91     return i;
     92 }
     93 
     94 int main()
     95 {
     96     prime_calc();
     97     cin>>T;
     98 //    cout<<cnt<<endl;
     99     while(T--)
    100     {
    101         cin>>n;
    102         int n1=0,m1=n;
    103         memset(A,0,sizeof(A));
    104         long long  k;
    105         for(int i=0; i<n; i++)
    106         {
    107             cin>>k;
    108             for(int j=0; j<cnt; j++){
    109                 while(k%prim[j]==0) {A[j][i]^=1;n1=max(n1,j+1);k=k/prim[j];}
    110             }//构造系数矩阵,系数只和奇偶性有关
    111         }
    112         cout<<(1LL<<(n-solve(n1,m1)))-1<<endl;//注意pow运算处理不了LL的数据,要么手写函数,要么移位运算
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    (CS模式)大学计算机基础考试系统
    四叶草的祝福
    做人的小故事!
    前天晚上回到北京了
    人生活的三种状态
    松口气了!
    Mysql一些基础用法
    云计算随想
    对vector与deque插值与遍历的性能数据
    gdb命令的常用调试选项
  • 原文地址:https://www.cnblogs.com/little-w/p/3570273.html
Copyright © 2011-2022 走看看