POJ 1830 开关问题 (高斯消元)
2013-10-31 19:15
381 查看
高斯消元分析
题意: 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开。你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态。对于任意一个开关,最多只能进行一次开关操作。你的任务是,计算有多少种可以达到指定状态的方法。(不计开关操作的顺序)
解法: 由开关之间的关联关系可建立n个方程,构成一个n阶增广矩阵,用高斯消元求解,若最后有k个自由元,则答案为2^k。时间复杂度为n^3。
题意: 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开。你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态。对于任意一个开关,最多只能进行一次开关操作。你的任务是,计算有多少种可以达到指定状态的方法。(不计开关操作的顺序)
解法: 由开关之间的关联关系可建立n个方程,构成一个n阶增广矩阵,用高斯消元求解,若最后有k个自由元,则答案为2^k。时间复杂度为n^3。
/* Created Time: Thursday, October 31, 2013 PM06:37:21 CST */ #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int M = 33; int n,g[M][M]; int Gauss() { int k,col; for (k = 0,col = 0; k<n && col<n; k++,col++) { int max_r = k; for (int i = k+1; i < n; i ++) if (g[i][col]>g[max_r][col]) max_r = i; if (g[max_r][col]==0) { k--; continue; } if (max_r!=k) for (int j = col; j <= n; j ++) swap(g[k][j],g[max_r][j]); for (int i = k+1; i < n; i ++) if (g[i][col]) for (int j = col; j <= n; j ++) g[i][j] ^= g[k][j]; } for (int i = k; i < n; i ++) if (g[i][col]) return -1; return 1<<(n-k); } int main() { int cas,a,b; scanf("%d",&cas); while (cas--) { scanf("%d",&n); memset(g,0,sizeof(g)); for (int i = 0; i < n; i ++) scanf("%d",&g[i] ); for (int i = 0; i < n; i ++) { scanf("%d",&a); g[i][i] = 1; g[i] ^= a; } while (~scanf("%d%d",&a,&b),a||b) g[b-1][a-1] = 1; int ans = Gauss(); if (ans<0) puts("Oh,it's impossible~!!"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 1830 开关问题 高斯消元 异或方程
- poj 1830 开关问题(高斯消元)
- 【高斯消元】【poj 1830】开关问题
- POJ 1830 开关问题 高斯消元
- POJ 1830 开关问题 高斯消元
- POJ 1830 开关问题(高斯消元)
- poj 1830 开关问题 高斯消元
- POJ-1830 开关问题 高斯消元
- POJ 1830 开关问题 高斯消元
- poj 1830 开关问题 高斯消元
- poj 1830 开关问题 (高斯消元)
- POJ 开关问题 1830【高斯消元求矩阵的秩】
- poj1830 开关问题解题报 <高斯消元>
- POJ 1830 开关问题 高斯消元求自由变元
- poj 1830 开关问题 高斯消元
- POJ 1830-开关问题(高斯消元求自由元个数)
- POJ 1830 开关问题(高斯消元)
- 开关问题 POJ 1830(高斯消元求解的个数)
- poj 1830 开关问题 (高斯消元)
- POJ 1830.开关问题(高斯消元)