HDU 3364 Lanterns (高斯消元)
析:同余高斯消元法,模板题,将每个开关控制每个灯列成行列式,最终状态是结果列,同余高斯消元,如果无解就是0,否则结果就是1<<(自由变元的个数);
代码如下:
#include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<math.h> using namespace std; const int maxn = 110; const int mod = 2; int a[maxn][maxn];//增广矩阵 int b[maxn][maxn]; int x[maxn];//解集 bool free_x[maxn];//标记是否是不确定的变元 int gcd(int a,int b) { return a == 0?b:gcd(b%a,a); } int lcm(int a,int b) { return a*b/gcd(a,b);//先除后乘防溢出 } // 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解,但无整数解, //-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数) //有equ个方程,var个变元。增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var. int Gauss(int equ,int var) { int i,j,k; int max_r;// 当前这列绝对值最大的行. int col;//当前处理的列 int ta,tb; int LCM; int temp; int free_x_num; int free_index; // for(int i=0;i<=var;i++) // { // x[i]=0; // free_x[i]=true; // } //转换为阶梯阵. col=0; // 当前处理的列 for(k = 0;k < equ && col < var;k++,col++) {// 枚举当前处理的行. // 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差) max_r=k; for(i=k+1;i<equ;i++) { if(abs(a[i][col])>abs(a[max_r][col])) max_r=i; } if(max_r!=k) {// 与第k行交换. for(j=k;j<var+1;j++) swap(a[k][j],a[max_r][j]); } if(a[k][col]==0) {// 说明该col列第k行以下全是0了,则处理当前行的下一列. k--; continue; } for(i=k+1;i<equ;i++) {// 枚举要删去的行. if(a[i][col]) { LCM = lcm(abs(a[i][col]),abs(a[k][col])); ta = LCM/abs(a[i][col]); tb = LCM/abs(a[k][col]); if(a[i][col]*a[k][col]<0)tb=-tb;//异号的情况是相加 for(j=col;j<var+1;j++) { a[i][j] = ((a[i][j]*ta-a[k][j]*tb)%mod+mod)%mod;//如果不是同模取余则改为a[i][j] = (a[i][j]*ta-a[k][j]*tb; } } } } // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0). for (i = k; i < equ; i++) { // 对于无穷解来说,如果要判断哪些是自由变元,那么初等行变换中的交换就会影响,则要记录交换. if (a[i][col]) return -1; } // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行,即说明没有形成严格的上三角阵. // 且出现的行数即为自由变元的个数. if (k < var) { //首先,自由变元有var - k个,即不确定的变元至少有var - k个. // for (i = k - 1; i >= 0; i--) // { // // 第i行一定不会是(0, 0, ..., 0)的情况,因为这样的行是在第k行到第equ行. // // 同样,第i行一定不会是(0, 0, ..., a), a != 0的情况,这样的无解的. // free_x_num = 0; // 用于判断该行中的不确定的变元的个数,如果超过1个,则无法求解,它们仍然为不确定的变元. // for (j = 0; j < var; j++) // { // if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j; // } // if (free_x_num > 1) continue; // 无法求解出确定的变元. // // 说明就只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的. // temp = a[i][var]; // for (j = 0; j < var; j++) // { // if (a[i][j] != 0 && j != free_index) temp -= a[i][j] * x[j]; // } // x[free_index] = temp / a[i][free_index]; // 求出该变元. // free_x[free_index] = 0; // 该变元是确定的. // } return var - k; // 自由变元有var - k个. } // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵. // 计算出Xn-1, Xn-2 ... X0. //需要解得时候就用下面的循环来解。 // for (i = var - 1; i >= 0; i--) // { // temp = a[i][var]; // for (j = i + 1; j < var; j++) // { // if (a[i][j] != 0) temp = ((temp - a[i][j]*x[j])%mod+mod)%mod;//temp -= a[i][j] * x[j]; // } // while(temp % a[i][i] != 0) temp+=mod;//如果不是同模取余,则temp % a[i][i] != 0时产生浮点数解 // x[i] = (temp / a[i][i])%mod; // if(x[i]<0)x[i]+=mod; // } return 0; } int main() { int i, j; int n,m,var; int t,kase = 1; scanf("%d",&t); while (t--) { memset(b,0,sizeof(b)); scanf("%d%d", &n, &var); for(int i = 0;i < var;i++) { int num; scanf("%d",&num); for(int j = 0;j < num;j++) { int nn; scanf("%d",&nn); b[nn-1][i] = 1; } } scanf("%d",&m); printf("Case %d:\n",kase++); while(m--) { memcpy(a,b,sizeof(b)); for(int i = 0;i < n;i++) { scanf("%d",&a[i][var]); } int ans = Gauss(n,var); if(ans == -1) printf("0\n"); else if(ans == 0) printf("1\n"); else printf("%I64d\n",1LL<<ans); } } return 0; }
HDU 3364 Lanterns (高斯消元)的更多相关文章
- HDU 3364 Lanterns 高斯消元
Lanterns Problem Description Alice has received a beautiful present from Bob. The present contains ...
- HDU 3949 XOR 高斯消元
题目大意:给定一个数组,求这些数组通过异或能得到的数中的第k小是多少 首先高斯消元求出线性基,然后将k依照二进制拆分就可以 注意当高斯消元结束后若末尾有0则第1小是0 特判一下然后k-- 然后HDU输 ...
- hdu 5755(高斯消元——模线性方程组模板)
PS. 看了大神的题解,发现确实可以用m个未知数的高斯消元做.因为确定了第一行的情况,之后所有行的情况都可以根据第一行推. 这样复杂度直接变成O(m*m*m) 知道了是高斯消元后,其实只要稍加处理,就 ...
- HDU 3949 XOR [高斯消元XOR 线性基]
3949冰上走 题意: 给你 N个数,从中取出若干个进行异或运算 , 求最后所有可以得到的异或结果中的第k小值 N个数高斯消元求出线性基后,设秩为$r$,那么总共可以组成$2^r$中数字(本题不能不选 ...
- Time travel HDU - 4418(高斯消元)
Agent K is one of the greatest agents in a secret organization called Men in Black. Once he needs to ...
- hdu 4870 rating(高斯消元求期望)
Rating Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu 6465 线性变换高斯消元
http://acm.hdu.edu.cn/showproblem.php?pid=6465 题意 给你三个点,再给你经过线性变换后的三个点,然后q次询问,给你一个点,需要你输出线性变换后的点 题解 ...
- HDU 3915 Game (高斯消元)
题意:有n堆石子,每个人只能从某一堆至少拿走一个,不能拿者败.问事先拿走某些堆的石子,使得先手必败. 析:将石子拆成二进制,未知数为1表示保留该堆石子,为0表示事先拿走该堆石子.最后求自由变元的数目, ...
- HDU 4870 Rating(高斯消元 )
HDU 4870 Rating 这是前几天多校的题目,高了好久突然听旁边的大神推出来说是可以用高斯消元,一直喊着赶快敲模板,对于从来没有接触过高斯消元的我来说根本就是一头雾水,无赖之下这几天做DP ...
随机推荐
- C#基本数据类型
在第一章我们了解了C#的输入.输出语句后,我这一节主要是介绍C#的基础知识,本节的内容也是后续章节的基础,好的开端等于成功的一半.在你阅读完本章后,你就有足够的C#知识编写简单的程序了.但还不能使用继 ...
- 在 VC6 中使用 GdiPlus-使用
下面用 VC6 来写一个 GdiPlus 的 Demo 工程 Step1:新建一个名为 Demo_GdiPlus 的 MFC AppWizard(exe) 工程 操作步骤:(1)主菜单File-> ...
- WEBUS2.0 In Action - 搜索操作指南 - (1)
上一篇:WEBUS2.0 In Action - 索引操作指南(2) | 下一篇:WEBUS2.0 In Action - 搜索操作指南(2) 1. IQueriable中内置的搜索功能 在Webus ...
- IOS中bounds和frame
* 用bounds和frame来修改尺寸是有一些小区别的 三.isEqual:方法 1> 系统会根据对象isEqual方法的返回值来决定两个对象是否相同 * 比如判断对象a和b是否相同,就会查看 ...
- LeetCode Reverse Nodes in k-Group 每k个节点为一组,反置链表
题意:给一个单链表,每k个节点就将这k个节点反置,若节点数不是k的倍数,则后面不够k个的这一小段链表不必反置. 思路:递归法.每次递归就将k个节点反置,将k个之后的链表头递归下去解决.利用原来的函数接 ...
- java实现的kmp算法
package DataStructure; import java.util.ArrayList; import java.util.List; //KMP算法的实现 //以下代码由freedom结 ...
- java动态代理复习
package com.free.testProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...
- Java中传值与传引用
不管Java参数类型是什么,一律传递参数的副本. <Thinking In Java>:“When you're passing primitives into a method,you ...
- 构建高性能web站点--读书大纲
用户输入你的站点网址,等了半天..还没打开,裤衩一下就给关了.好了,流失了一个用户.为什么会有这样的问题呢.怎么解决自己站点“慢”,体验差的问题呢. 在这段等待的时间里,到底发生了什么?事实上这并不简 ...
- rand.Read() 和 io.ReadFull(rand.Reader) 的区别?
golang的随机包 rand.go 中我们可以看到 rand.Read 其实是调用的io.Reader.Read() 1: // Package rand implements a cryptogr ...