POJ 2965 (枚举)

题意:
这个题和之前的1753差不多一样,主要就是只有全在open状态的时候才能开,,改变某个值的时候,这一行和
这一列都要进行反转,而且还得把最小步数一个一个打印出来,具体分析见POJ 1753
代码:

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int ans=35;
bool map[6][6];
int x[35],y[35];
int lastx[35],lasty[35];
int prints[6][6];
int printsans[6][6];

//判断整个矩阵的颜色是否全部都是open状态
bool judge()
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(map[i][j]!=true)
                return false;
    return true;
}

//对于选中的的地方,选中位置的这一行和这一列都变成相反的
void flip(int n)
{
    int i=n/4;//行
    int j=n%4;//列
    map[i][j]=!map[i][j];
    for(int m=0;m<4;m++)
    {
        map[i][m]=!map[i][m];
        map[m][j]=!map[m][j];
    }
}


//用dfs遍历全部格子
void dfs(int n,int a)
{
    if(judge())
    {
        if(ans>a){
            ans=a;
            for(int f=0;f<4;f++)
            {
                for(int g=0;g<4;g++)
                {
                    printsans[f][g]=prints[f][g];
                }
            }
        }
        return ;
    }
    if(n>=16)
        return ;


    int i=n/4;//行
    int j=n%4;//列

    dfs(n+1,a);

    flip(n);//进行了反转
    prints[i][j]=1;
    dfs(n+1,a+1);
    prints[i][j]=-1;
    flip(n);//最后反转,恢复原状
}

int main()
{
    char c;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
        {
            cin>>c;
            if(c=='+')
                map[i][j]=false;
            else
                map[i][j]=true;
        }

    dfs(0,0);
    cout<< ans <<endl;



    for(int f=0;f<4;f++)
    {
        for(int g=0;g<4;g++)
        {
            if(printsans[f][g]==1)
                cout<<f+1<<" "<<g+1<<endl;
        }
    }

    return 0;

}

打印还有其他的方式:


#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int ans=35;
bool map[6][6];
int x[35],y[35];
int lastx[35],lasty[35];

//判断整个矩阵的颜色是否全部都是open状态
bool judge()
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(map[i][j]!=true)
                return false;
    return true;
}

//对于选中的的地方,选中位置的这一行和这一列都变成相反的
void flip(int n)
{
    int i=n/4;//行
    int j=n%4;//列
    map[i][j]=!map[i][j];
    for(int m=0;m<4;m++)
    {
        map[i][m]=!map[i][m];
        map[m][j]=!map[m][j];
    }
}


//用dfs遍历全部格子
void dfs(int n,int a)
{
    if(judge())
    {
        if(ans>a){
            ans=a;
            for(int f=0;f<ans;f++)
            {
                lastx[f]=x[f];
                lasty[f]=y[f];
            }
        }
        return ;
    }
    if(n>=16)
        return ;


    int i=n/4;//行
    int j=n%4;//列

    dfs(n+1,a);

    flip(n);//进行了反转
    x[a]=i;
    y[a]=j;
    dfs(n+1,a+1);

    flip(n);//最后反转,恢复原状
}

int main()
{
    char c;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
        {
            cin>>c;
            if(c=='+')
                map[i][j]=false;
            else
                map[i][j]=true;
        }

    dfs(0,0);
    cout<< ans <<endl;

    for(int i=0;i<ans;i++)
    {
        cout << lastx[i]+1 << " " << lasty[i]+1 << endl;
    }

    return 0;

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJ1753的题目描述为:有一个4×4的棋盘,棋盘中有16个棋子,其中有14个棋子是黑色的,用B表示;另外两个棋子是白色的,用W表示。现在要求移动棋子,将两个白色棋子移到一起,移动棋子方式是把与白色棋子相邻(上下左右,而非斜向相邻)的棋子移到空位上。现在,请你求出最少需要移动多少次。 题目看起来很简单,但是要考虑各种情况,一般在处理类似的搜索问题时,我们使用Breath First Search (BFS)来解决问题。 BFS 是一种优秀的遍历搜索算法,广泛应用于许多问题,特别是计算机科学和人工智能。BFS 只需要进行一次完整的搜索即可找到问题的最短路径或解决方案。 在这道题目中,我们可以使用 BFS 来解决问题。 我们首先需要定义状态的表示方式,可以这么表示: 1. 4*4的数组board表示状态。 2. 一个结构体Node,代表搜索树的每个节点。其中状态的表示形式为board。还有一些列信息,包括横,纵坐标,深度depth,以及方向dir。 我们使用 queue 来存储每一层需要遍历的结点,对于每个结点,我们枚举它可以到达的状态,并将这些状态添加到队列中,继续进行下一层的遍历。直到达到目标状态。 因此,我们的搜索过程主要包括以下的步骤: 1. 判断当前状态是否是目标状态 2. 枚举当前状态可能到达的所有状态,并判断是否合法 3. 如果该状态未被访问过,添加该状态,进行遍历。 知道了上面的步骤,我们就可以使用 bfs 来解决问题了。 具体实现可以参考以下代码:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值