POJ2965——The Pilots Brothers' refrigerator

The Pilots Brothers' refrigerator

Description

The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.

There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.

The task is to determine the minimum number of handle switching necessary to open the refrigerator.

Input

The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.

Output

The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.

Sample Input

-+--
----
----
-+--

Sample Output

6
1 1
1 3
1 4
4 1
4 3
4 4
题目大意:给了一个4*4的棋盘,每个格子有正负两种状态,设任意一组数(i,j),将第i行与第j列全部翻转正负。输出使棋盘变为全负的最少步骤,并打印任意一种最短步骤过程。
     方法与POJ1753相似,均为位运算+BFS
解题思路:同POJ1753 用十六个二进制数来表示当前棋盘状态,用位运算来翻转正负,用bfs来求出最短距离。
     用step[]和father[]来存储当前状态的父节点和翻转的(i,j)。
     搜素完后 根据step和father两个数组反向找,并输出(若一组(i,j)可以使其完成翻转,那么改组的倒序也可以??)
PS:对于一个状态1进行(i1,j1)(i2,j2)。。。(in,jn)进行翻转后到达状态2。
  那么对状态1进行(in,jn)。。。(i1,j1)进行翻转后同样能到达状态2。
 1 #include<stdio.h>
 2 int vis[70000]= {0},dis[70000],father[70000],step[70000];//father表示当前下标状态的父节点状态,step表示父节点是如何变幻成当前状态的
 3 int c=1,queue[65535*2];
 4 int fz(int a,int xy)//通过位运算进行翻转
 5 {
 6     int tmp=1,x1,y1;
 7     tmp=tmp<<(xy-1);
 8     a=a^tmp;
 9     x1=xy/4,y1=xy%4;
10     if (y1==0) y1=4;
11     else x1++;
12     if (x1==1) a=a^0x000F;
13     if (x1==2) a=a^0x00F0;
14     if (x1==3) a=a^0x0F00;
15     if (x1==4) a=a^0xF000;
16     if (y1==1) a=a^0x1111;
17     if (y1==2) a=a^0x2222;
18     if (y1==3) a=a^0x4444;
19     if (y1==4) a=a^0x8888;
20     return a;
21 }
22 int bfs(int a)
23 {
24     int i,t,front=0,rear=1,tmp=5,ok;
25     dis[a]=0,vis[a]=1;
26     step[a]=0,father[a]=-1;
27     queue[front]=a;
28     while (front<rear)
29     {
30         for (i=1; i<=16; i++)
31         {
32             tmp=fz(queue[front],i);
33             if (vis[tmp]==0)
34             {
35                 father[tmp]=queue[front];
36                 step[tmp]=i;
37                 queue[rear]=tmp;
38                 vis[tmp]=1;
39                 dis[rear++]=dis[front]+1;
40                 if (tmp==0)
41                 {
42                     c=dis[rear-1];
43                     return tmp;
44                 }
45             }
46         }
47         front++;
48     }
49     return 1;
50 }
51 int main()
52 {
53     char tmp[20];
54     int k,a,i,t=0,x1,y1,j;
55     for (i=1; i<=16; i++)
56     {
57         scanf("%c",&tmp[i]);
58         if (i%4==0&&i!=16) getchar();
59     }
60     k=1,a=0;
61     for (i=16; i>=1; i--)//将状态转换成整数(eg:-+-+为0101)
62     {
63         if (tmp[i]=='+') a+=k;
64         k*=2;
65     }
66     t=bfs(a);
67     printf("%d
",c);
68     i=0;
69     while (father[t]!=-1)
70     {
71         j=step[t];
72         x1=j/4,y1=j%4;
73         if (y1==0) y1=4;
74         else x1++;
75         x1=5-x1,y1=5-y1;
76         printf("%d %d
",x1,y1);
77         t=father[t];
78     }
79     return 0;
80 }
原文地址:https://www.cnblogs.com/Enumz/p/3761323.html