一个电冰箱有16个把手,每个把手两种状态(开‘-’或关‘+’),只有在所有把手都打开时,门才开。把手是按照4*4的矩阵分布的,可以改变任意一个把手的状态,但会同时改变其所在行和列的所有把手的状态。现在给你一种冰箱的初始状态,求最小步骤使得冰箱打开。
输入格式
输入文件名:da.in
第一行为整数t(≤10),表示测试数据组数;每组数据为四行,每行四个字符,只包含“+”和“-”,每两组数据之间有一个空行。
输出格式
输出文件名:da.out
对于每组数据,输出最少步骤。
输入/输出例子1
输入:
2
-+--
----
----
-+--
+-++
++++
-+--
+-++
-+-----------+--
0100000000000100
输出:
6
9
样例解释
可以改变第一行1,3,4和第四行1,3,4六个把手,6步后,全部变成‘-’,即打开冰箱。
AK code:
#include<bits/stdc++.h>
using namespace std;
int c[16]={0xf888,0xf444,0xf222,0xf111,
0x8f88,0x4f44,0x2f22,0x1f11,
0x88f8,0x44f4,0x22f2,0x11f1,
0x888f,0x444f,0x222f,0x111f};
int q[100005],s[100005];
int main()
{
freopen("da.in","r",stdin);
freopen("da.out","w",stdout);
char p[5];
int t;
cin>>t;
while(t--)
{
int w=0;
for(int i=0;i<4;i++)
{
scanf("%s",p);
for(int j=0;j<4;j++)
{
w=w<<1|(p[j]=='+');
}
}
memset(s,-1,sizeof(s));
int f=0,r=0;
q[r++]=w;
s[w]=0;
while(f!=r&&s[0]==-1){
w=q[f++];
for(int i=0;i<16;i++){
int u=w^c[i];
if(s[u]==-1){
s[u]=s[w]+1;
q[r++]=u;
}
if(u==0)break;
}
}
cout<<s[0]<<endl;
}
return 0;
}