题目:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 34731 | Accepted: 15207 |
Description
Input
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
Source
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include<climits> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <numeric> #include <iomanip> #include <bitset> #include <list> #include <stdexcept> #include <functional> #include <utility> #include <ctime> using namespace std; #define PB push_back #define MP make_pair #define REP(i,x,n) for(int i=x;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define FORD(i,h,l) for(int i=(h);i>=(l);--i) #define SZ(X) ((int)(X).size()) #define ALL(X) (X).begin(), (X).end() #define RI(X) scanf("%d", &(X)) #define RII(X, Y) scanf("%d%d", &(X), &(Y)) #define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z)) #define DRI(X) int (X); scanf("%d", &X) #define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y) #define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z) #define OI(X) printf("%d",X); #define RS(X) scanf("%s", (X)) #define MS0(X) memset((X), 0, sizeof((X))) #define MS1(X) memset((X), -1, sizeof((X))) #define LEN(X) strlen(X) #define F first #define S second #define Swap(a, b) (a ^= b, b ^= a, a ^= b) #define Dpoint strcut node{int x,y} #define cmpd int cmp(const int &a,const int &b){return a>b;} /*#ifdef HOME freopen("in.txt","r",stdin); #endif*/ const int MOD = 1e9+7; typedef vector<int> VI; typedef vector<string> VS; typedef vector<double> VD; typedef long long LL; typedef pair<int,int> PII; //#define HOME int Scan() { int res = 0, ch, flag = 0; if((ch = getchar()) == '-') //判断正负 flag = 1; else if(ch >= '0' && ch <= '9') //得到完整的数 res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9' ) res = res * 10 + ch - '0'; return flag ? -res : res; } /*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/ const int MAXN=50; int a[MAXN][MAXN];//增广矩阵 int x[MAXN];//解集 int free_x[MAXN];//标记是否是不确定的变元 void Debug(int equ,int var) { int i, j; for (i = 0; i < equ; i++) { for (j = 0; j < var + 1; j++) { cout << a[i][j] << " "; } cout << endl; } cout << endl; } inline int gcd(int a,int b) { int t; while(b!=0) { t=b; b=a%b; a=t; } return a; } inline int lcm(int a,int b) { return a/gcd(a,b)*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]=0; } free_x_num=0; //转换为阶梯阵. 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--; free_x[free_x_num++]=col; continue; } for(i=k+1;i<equ;i++) {// 枚举要删去的行. if(a[i][col]!=0) { 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]^a[k][j]; } } } } //Debug(equ,var); // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0). for (i = k; i < equ; i++) { // 对于无穷解来说,如果要判断哪些是自由变元,那么初等行变换中的交换就会影响,则要记录交换. if (a[i][col] != 0) return -1; } // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行,即说明没有形成严格的上三角阵. // 且出现的行数即为自由变元的个数. //if (k < var) // { // 首先,自由变元有var - k个,即不确定的变元至少有var - k个. // Debug(equ,var); 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 ^= a[i][j] && x[j]; } if (temp % a[i][i] != 0) return -2; // 说明有浮点数解,但无整数解. x[i] = temp / a[i][i]; } return 0;*/ } char mp[4][4]; int main() {//freopen("out.txt","w",stdout); for(int i=0;i<4;i++) {for(int j=0;j<4;j++) scanf("%c",&mp[i][j]); //printf("%c",mp[i][j]);} // printf("\n"); getchar(); } MS0(a); for(int i=0;i<4;i++) for(int j=0;j<4;j++) { int k=i*4+j; if(mp[i][j]=='b') a[k][16]=0; else a[k][16]=1; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) { int t=i*4+j; a[t][t]=1; if(i!=0) a[(i-1)*4+j][t]=1; if(i!=3) a[(i+1)*4+j][t]=1; if(j!=0) a[i*4+(j-1)][t]=1; if(j%4!=3) a[i*4+j+1][t]=1; } int ans=Gauss(16,16); if(ans==-1||ans==-2) ans=INT_MAX; else { /*if(ans==0) {for(int i=0;i<16;i++) ans+=x[i];}*/ // else // { int t=ans; ans=INT_MAX; int tot=(1<<t); for(int i=0;i<tot;i++) { int cnt=0; int index=i; for(int j=0;j<t;j++) { x[free_x[j]]=(index&1); if(x[free_x[j]]) cnt++; index>>=1; } for(int j=16-t-1;j>=0;j--) { int temp = a[j][16]; //int tt=0; //while(a[j][tt]==0) // tt++; for (int k = j+1; k < 16; k++) { if (a[j][k] != 0) temp ^= x[k]; } // if (temp % a[j][j] != 0) return -2; // 说明有浮点数解,但无整数解. x[j] = temp/a[j][j] ; cnt+=x[j]; } ans=min(ans,cnt); } // } } MS0(a); for(int i=0;i<4;i++) for(int j=0;j<4;j++) { int k=i*4+j; if(mp[i][j]=='b') a[k][16]=1; else a[k][16]=0; } for(int i=0;i<4;i++) for(int j=0;j<4;j++) { int t=i*4+j; a[t][t]=1; if(i!=0) a[(i-1)*4+j][t]=1; if(i!=3) a[(i+1)*4+j][t]=1; if(j!=0) a[i*4+(j-1)][t]=1; if(j%4!=3) a[i*4+j+1][t]=1; } int ans2=Gauss(16,16); if(ans2==-1||ans2==-2) ans2=INT_MAX; else { /*if(ans2==0) {for(int i=0;i<16;i++) ans2+=x[i];} else {*/ int t=ans2; ans2=INT_MAX; int tot=(1<<t); for(int i=0;i<tot;i++) { int cnt=0; int index=i; for(int j=0;j<t;j++) { x[free_x[j]]=index&1; if( x[free_x[j]]) cnt++; index>>=1; } for(int j=16-t-1;j>=0;j--) { int temp = a[j][16]; // int tt=0; // while(a[j][tt]==0) // tt++; for (int k = j+1; k < 16; k++) { if (a[j][k] != 0) temp ^= x[k]; } // if (temp % a[j][j] != 0) return -2; // 说明有浮点数解,但无整数解. x[j] = temp/a[j][j] ; cnt+=x[j]; } ans2=min(ans2,cnt); } //} } int res=min(ans,ans2); if(res==INT_MAX) { printf("Impossible\n"); } else printf("%d\n",res); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 1753 Flip Game(高斯消元法,枚举自由变元)
原文地址:http://blog.csdn.net/u013840081/article/details/48009767