POJ 1830 开关问题 (高斯消元)
题意:中文题,和上篇博客POJ 1222是一类题。
题解:如果有解,解的个数便是2^(自由变元个数),因为每个变元都有两种选择。
代码:
#include <iostream> #include <cmath> #include <cstring> #include <cstdio> using namespace std; int s[35],e[35],g[35][35],n; int gauss() { int row,col; for(row=0,col=0;row<n&&col<n;col++) { int id=row; for(int i=row;i<n;i++) if(g[i][col]) id=i; if(g[id][col]) { for(int k=col;k<=n;k++) swap(g[id][k],g[row][k]); for(int i=row+1;i<n;i++) if(g[i][col]) for(int k=col;k<=n;k++) g[i][k]^=g[row][k]; row++; } } for(int i=row;i<n;i++) if(g[i][n]) return -1; return 1<<(n-row); } int main() { //注意一定不要在主函数里定义n 这样会在输入的时候覆盖全局变量n int t; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(g,0,sizeof(g)); for(int i=0;i<n;i++) scanf("%d",&s[i]); for(int i=0;i<n;i++) { scanf("%d",&e[i]); g[i][n]=s[i]^e[i]; g[i][i]=1; } int a,b; for(;;) { scanf("%d%d",&a,&b); if(a==0&&b==0) break; //这里注意题目中的下标是从1开始的 //而且ab不能写反 至于为什么不能写反还不清楚 g[b-1][a-1]=1; } int ans=gauss(); if(ans==-1) puts("Oh,it's impossible~!!"); else printf("%d\n",ans); } return 0; }