poj2965

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37667021/article/details/78054883

     原题链接

The Pilots Brothers' refrigerator
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 27192   Accepted: 10499   Special Judge

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

http://blog.csdn.net/freezhanacmore/article/details/9406679

题意:有一个4*4的矩阵,每个位置上不是‘+’(代表小门关着)就是‘-’(代表小门开着),所有的小门开着,这个冰箱才开着。若操作(i,j)则(i,j)所在的行和列都改变

           符号,问最少多少次可以打开门(即全部变成‘-’号),并输出路径

思路:bfs+状态压缩+记录路径


这道题跟poj1753差不多的,只是比1753多要求输出路径

poj1753链接


因为要输出路径,可以用结构体数组模拟队列


本文是状态压缩是以左上为高位

例如:

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

转成二进制0100 0000 0000 0100

‘-’代表0,‘+’代表1

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct point
{
    int state;//当前状态
    int x,y;//记录得到当前状态操作的坐标
    int pre;//记录前一个状态在que中的位置
};

int begin_que,rear;
point que[65535];

int vis[65537];//用来是否被访问过
int flip(int state,int i,int j)
{
    int k;
    int new_state=state;
    i=4-i;
    j=4-j;
    new_state^=(0x1<<(4*i+j));//这个位操作可以直接改变(i,j)上的符号
    for(k=0; k<4; k++)
    {
        new_state^=(0x1<<(4*k+j));
    }
    for(k=0; k<4; k++)
    {
        new_state^=(0x1<<(4*i+k));
    }
    return new_state;
}
void print(int s)//程序退出时已经到最终状态了,而路径是从开始到结束,故用递归
{
    if(s!=0)
    {
        print(que[s].pre);
        printf("%d %d\n",que[s].x,que[s].y);
    }
}
int bfs(point state)
{
    int i,j;
    begin_que=rear=0;
    int step=0;
    point tmp1,tmp2;
    point *p;
    memset(vis,0,sizeof(vis));
    int count_que;
    que[rear++]=state;
    vis[state.state]=1;
    while(rear>begin_que)
    {
        count_que=rear-begin_que;
        while(count_que>0)
        {
            count_que--;
            tmp1=que[begin_que++];
            if(tmp1.state==0)//如果为0,那么说明所有位置上全为0,打印结果并退出
            {
                printf("%d\n",step);
                print(begin_que-1);
                return step;
            }
            for(i=1; i<=4; i++)//得到tmp1这个状态后,要对16个位置都进行一次操作
                for(j=1; j<=4; j++)
                {
                    tmp2.state=flip(tmp1.state,i,j);
                    if(vis[tmp2.state]==0)
                    {
                        vis[tmp2.state]=1;
                        tmp2.x=i;
                        tmp2.y=j;
                        tmp2.pre=begin_que-1;
                        que[rear++]=tmp2;
                    }
                }
        }
//        if(vis[0])
//        {
//            printf("%d\n",888888);
//            break;
//        }
        step++;
    }
    return -1;
}

int main()
{
    int i,j,k;
    int state;
    point start;
    char ch[6];
    while(scanf("%s",ch)!=EOF)
    {
        state=0;
        for(i=0; i<4; i++)
        {
            state=state<<1;
            if(ch[i]=='+')state+=1;
        }
        getchar();
        for(j=0; j<3; j++)
        {
            scanf("%s",ch);
            for(i=0; i<4; i++)
            {
                state=state<<1;
                if(ch[i]=='+')state+=1;
            }
            getchar();
        }
        start.state=state;
       // printf("%d\n",state);
        start.x=-1;
        start.pre=-1;
      bfs(start);
    }
    return 0;
}
/*
-+--
----
----
-+--

1 3
1 4
4 1
*/




猜你喜欢

转载自blog.csdn.net/m0_37667021/article/details/78054883