POJ - 1681: Painter's Problem (开关问题-高斯消元)
pro:开关问题,同上一题。 不过只要求输出最小的操作步数,无法完成输出“inf”
sol:高斯消元的解对应的一组合法的最小操作步数。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int a[250][250],ans[250]; int x[5]={0,0,0,1,-1}; int y[5]={0,1,-1,0,0}; bool Guass(int N) { rep(i,0,N-1){ int mark=i; rep(j,i+1,N-1) if(abs(a[j][i])>abs(a[mark][i])) mark=j; if(mark!=i) rep(j,0,N) swap(a[i][j],a[mark][j]); if(!a[i][i]) continue; rep(j,i+1,N){ if(!a[j][i]) continue; rep(k,i,N){ a[j][k]^=a[i][k]; } } } for(int i=N-1;i>=0;i--){ if(!a[i][i]&&a[i][N]) return false;//无解 ans[i]=a[i][N]&a[i][i]; rep(j,0,i-1) a[j][N]^=(a[j][i]&ans[i]); } return true; } char c[30][30]; int main() { int T,N; scanf("%d",&T); while(T--){ memset(a,0,sizeof(a)); scanf("%d",&N); rep(i,0,N-1) scanf("%s",c[i]); rep(i,0,N-1) rep(j,0,N-1) a[i*N+j][N*N]=(c[i][j]!='y'); rep(i,0,N-1) rep(j,0,N-1) { int t=i*N+j; rep(k,0,4) { if(i+x[k]>=0&&i+x[k]<N&&j+y[k]>=0&&j+y[k]<N){ a[(i+x[k])*N+j+y[k]][t]=1; } } } if(Guass(N*N)){ int res=0; rep(i,0,N*N-1) res+=ans[i]; printf("%d\n",res); } else puts("inf"); } return 0; }
It is your time to fight!