hdu3364 高斯消元1(开关控制灯,异或解的个数)

本文介绍了一种使用高斯异或消元法解决特定开关控制灯泡问题的算法实现,通过矩阵操作来确定可能的开关组合方案数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

n个灯,m个开关,某个开关能同时控制某些灯 。 问达到最终状态的方案数
高斯异或消元,答案为2^x  x为自由变量的个数或无解

具体消元代码注释:think!!

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,m,g[105][105],a[105][105];
 6 long long guass()
 7 {
 8   int row=1,col,i,j;
 9   for (col=1;col<=m;col++)
10   {
11     for (i=row;i<=n;i++)
12       if (g[i][col]) break; //找到该列第一个1
13     if (i>n) continue; //该列全0,看下一列
14     if (i!=row)
15       for (j=col;j<=m+1;j++)
16         swap(g[i][j],g[row][j]); //将i行与该列非0行交换
17     for (i=row+1;i<=n;i++)
18       if (g[i][col])
19       {
20         for (j=col;j<=m+1;j++)
21           g[i][j]^=g[row][j]; //高斯异或消元
22       }
23     row++;
24   }
25   for (i=row;i<=n;i++)
26     if (g[i][m+1]) return 0;//0 0 0 0 1 则无解
27   long long ans=1;
28   for (i=1;i<=m-row+1;i++)  //2的自由变量次方
29     ans=ans*2;
30   return ans;
31 }
32 int main()
33 {
34   int T,t,i,j,k,x,q;
35   scanf("%d",&T);
36   for (t=1;t<=T;t++)
37   {
38     printf("Case %d:\n",t);
39     scanf("%d%d",&n,&m);
40     memset(a,0,sizeof(a));
41     for (i=1;i<=m;i++)
42     {
43       scanf("%d",&k);
44       for (j=1;j<=k;j++)
45       {
46         scanf("%d",&x);
47         a[x][i]=1;
48       }
49     }
50     scanf("%d",&q);
51     while (q--)
52     {
53       for (i=1;i<=n;i++)
54         scanf("%d",&g[i][m+1]);
55       for (i=1;i<=n;i++)
56         for (j=1;j<=m;j++)
57           g[i][j]=a[i][j];
58       printf("%I64d\n",guass());
59     }
60   }
61   return 0;
62 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3364

转载于:https://www.cnblogs.com/xiao-xin/articles/4162685.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值