poj2965The Pilots Brothers' refrigerator

背景:和poj1753一样,用dfs就可以做出来,只是和1753相比较得输出一些步骤,不过这也不麻烦,直接用两个数组就可以存储了。不过记住当递归回来的时候记住把数组里面对应位置的元素清零。

思路:同上一篇1753.

#include <stdio.h>
#include <string.h>
int q[4][4],ok=0,r[16],c[16];
int iswin(void)
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(q[i][j]!=1) return 0;
    return 1;
}
void change(int i,int j)
{
    q[i][j]=!q[i][j];
    for(int k=0;k<4;k++)
    {
        q[i][k]=!q[i][k];
        q[k][j]=!q[k][j];
    }
}
void dfs(int m,int sum,int a,int b)
{
    if(ok) return;
    else if(m==sum)
    {
        if(iswin())
        {
            ok=1;
            printf("%d\n",sum);
            for(int k=0;k<sum;k++)
                printf("%d %d\n",r[k],c[k]);
        }
        else return;
    }
    else
    {
        for(int i=a;i<4;i++)
        {
            for(int j=b;j<4;j++)
            {
                r[m]=i+1;c[m]=j+1;
                change(i,j);
                if(j<3)  dfs(m+1,sum,i,j+1);
				else {dfs(m+1,sum,i+1,0);b=0;}
                change(i,j);
                r[m]=0;c[m]=0;
            }
        }
        return;
    }
}
int main(void)
{
    char ch;
    memset(r,0,sizeof(r));
    memset(c,0,sizeof(c));
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
        {
            scanf("%c",&ch);
            if(j==3) getchar();
            q[i][j]=(ch=='+')?0:1;
        }
    if(iswin()) {printf("%d\n",0);return 0;}
    for(int k=1;k<=16;k++)
    {
        dfs(0,k,0,0);
        if(ok) break;
    }
    return 0;
}

在网上看到有这样用递归的,感觉好高大上。

虽然他写的代码,我有一些地方不懂,不过这些都是我要学习的东西。

他的思路:

1.一个元素翻转奇数次状态不变,翻转偶数次状态改变

由1容易推到出2

2:要想把第Sij翻转,同时保持第i行和第j列其他元素状态不变,sij本身翻转两次,第i和第j列的其他元素翻转一次.

由把所有状态为关的元素都做一次2操作,记录那些元素状态变化过,变化过的元素个数即最小步骤数.

由以上分析得出,各个元素的步骤顺序其实是无所谓的.把变化的过元素按任意顺序输出即步骤.

附代码:

#include <iostream>
#include <queue>
bool mark[4][4];
struct Pos
{
    int x;
    int y;
};
std::queue<Pos> Ans;
int input()
{
    memset(mark,0,sizeof(mark));
    int i ,j,k;
    char ch;
    for (i = 0 ;i < 4 ; ++ i)
    {
        for (j = 0 ;j < 4 ; ++j)
        {
            ch = getchar();
            if ('+' == ch)
            {
                mark[i][j] = !mark[i][j];
                for(k = 0 ; k < 4 ; k ++)
                {
                    mark[i][k] = !mark[i][k];
                    mark[k][j] = ! mark[k][j];
                }
            }
        }
        getchar();
    }
    return 0;
}
int main()
{
    int nStep = 0;
    int i,j;
    input();
    for ( i = 0 ; i < 4; ++i)
    {
        for (j = 0 ; j < 4 ; ++j)
        {
            if (mark[i][j])
            {
                nStep ++;
                Pos pos;
                pos.x = i + 1;
                pos.y = j + 1;
                Ans.push(pos);
            }
        }
    }
    std::cout <<nStep<<std::endl;
    while (!Ans.empty())
    {
        Pos pos = Ans.front();
        Ans.pop();
        std::cout<<pos.x<<" "<<pos.y<<std::endl;
    }
    return 0;
} 

poj2965The Pilots Brothers' refrigerator

时间: 2025-01-16 21:34:27

poj2965The Pilots Brothers' refrigerator的相关文章

【递归】POJ2965-The Pilots Brothers&#39; refrigerator

和POJ1753的方法一致,唯一不同的是需要记录路径,只需添加一个全集变量的path路径即可. 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int INF=100000; 5 int map[4][4]; 6 int path[4][4]; 7 int maxpath[4][4]; 8 int ans=INF; 9 10 void open(int step,int turn) 11

poj2965The Pilots Brothers&#39; refrigerator DFS+枚举

The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20858   Accepted: 8048   Special Judge Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to o

The Pilots Brothers&#39; refrigerator - poj 2965

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20325   Accepted: 7830   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 handle

poj 2965 The Pilots Brothers&#39; refrigerator[ 枚举 ]

传送门:http://poj.org/problem?id=2965 思路:二进制枚举,递归输出路径.G++ 900+Ms勉强过,C++超时. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map>

POJ 2965 The Pilots Brothers&#39; refrigerator

原题链接:http://poj.org/problem?id=2965 简单的dfs,因为是要求最小值,枚举深度来得到递归终止条件,和 poj1753很像,毕竟是放在一起的. #include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <cmath> #include <cstdlib> #include <vector&g

poj2965 The Pilots Brothers&#39; 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 refri

POJ 2965-The Pilots Brothers&#39; refrigerator(贪心+枚举)

The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19464   Accepted: 7462   Special Judge Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to o

POJ 2965:The Pilots Brothers&#39; refrigerator

The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18080   Accepted: 6855   Special Judge Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to o

POJ 1965 The Pilots Brothers&#39; refrigerator 搜索

The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18222   Accepted: 6936   Special Judge Description The game "The Pilots Brothers: following the stripy elephant" has a quest where a player needs to o