POJ1753 + POJ2965 翻牌问题 DFS方法(枚举)

之前写过非DFS方法,附上链接:https://blog.csdn.net/Cc_Sonia/article/details/89432031

今天再回过头用DFS方法,,发现,,好暴力啊。。。就是一个个枚举,看翻还是不翻。。这两道题用DFS就基本没什么区别了,主要是第二道要记录路径。附上两题的AC代码如下:(果然时间慢了好多好多。。)

POJ1753:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;

char s[7][7];
int n,ans;
void change(int x,int y)
{
    if(s[x][y]=='b') s[x][y]='w';
    else s[x][y]='b';
}
void flip(int x,int y)
{
    change(x,y);
    if(x>0) change(x-1,y);
    if(y>0) change(x,y-1);
    if(x<n-1) change(x+1,y);
    if(y<n-1) change(x,y+1);
}
bool judge()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(s[i][j]!=s[0][0])
                return false;
    return true;
}

void dfs(int x,int y,int num) //遍历每个棋子
{
    if(judge())
    {
        ans=min(ans,num);
        return;
    }
    if(x>=n||y>=n)//注意!
        return;
    //"下一个"棋子
    int yy=(y+1)%n;
    int xx=x+(y+1)/n;
    dfs(xx,yy,num);//本身没有翻转
    flip(x,y);//注意是x,y!不是xx,yy!
    dfs(xx,yy,num+1);
    flip(x,y);//再翻回来,相当于没变
}
int main()
{
    n=4;
    for(int i=0;i<n;i++)
        scanf("%s",s[i]);
    ans=INF;
    dfs(0,0,0);
    if(ans==INF) printf("Impossible\n");
    else printf("%d\n",ans);
	return 0;
}

POJ2965:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
#define mkp make_pair
typedef pair<int,int> pp;

char s[7][7];
int n,ans;
pp aans[20],tmp[20];
void change(int x,int y)
{
    if(s[x][y]=='+') s[x][y]='-';
    else s[x][y]='+';
}
void flip(int x,int y)
{
    change(x,y);
    for(int i=0;i<n;i++)
        if(i!=x) change(i,y);//同一列
    for(int i=0;i<n;i++)
        if(i!=y) change(x,i);//同一行
}
bool judge()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            if(s[i][j]!='-')
                return false;
    return true;
}

void dfs(int x,int y,int num)
{
    if(judge())
    {
        if(num<ans)
        {
            ans=num;
            for(int i=0;i<num;i++)//记录答案
                aans[i]=tmp[i];
        }
        return;
    }
    if(x>=n||y>=n)//注意!
        return;
    int yy=(y+1)%n;
    int xx=x+(y+1)/n;
    dfs(xx,yy,num);
    flip(x,y);
    tmp[num].first=x,tmp[num].second=y;//记录路径
    dfs(xx,yy,num+1);
    flip(x,y);
}
int main()
{
    n=4;
    for(int i=0;i<n;i++)
        scanf("%s",s[i]);
    ans=INF;
    memset(tmp,0,sizeof(tmp));
    dfs(0,0,0);
    if(ans==INF)
        printf("Impossible\n");
    else
    {
        printf("%d\n",ans);
        for(int i=0;i<ans;i++)
            printf("%d %d\n",aans[i].first+1,aans[i].second+1);
    }
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值