五香豆腐_ssl2357_bfs+位运算

66 篇文章 0 订阅

Description


 经过谢老师n次的教导,pige终于觉悟了——过于腐败是不对的。但是pige自身却无法改变自己,于是他找到了你,请求你的帮助。
pige的内心可以看成是5*5个分区组成,每个分区都可以决定的的去向,0表示继续爱好腐败,1表示改正这个不良的习惯。只有当25个分区都为1时,pige才会改正腐败这个不良习惯。你有一根神奇的魔法棒,可以使点中的分区以及这个分区上下左右改变(1变0,0变1)。这根神奇的魔法棒只能使用6次了,请问你最少使用多少次才可以救醒这pige。(使用超过6次则输出-1,表示pige已经无药可救了)。(因为pige实在太顽固不化,所以你要救醒他n次,但每次都有会获得由谢老师送的一根新的魔法棒,不过之前那根会消失)。

Input


 第一行有一个正整数n,代表数据中共有n组数据。
  以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了25个分区的初始状态。各组数据间用一个空行分隔。

Output


输出数据一共有n行,每行有一个小于等于6的整数,它表示对于输入数据中对应的每组数据最少需要几步才能将救醒pige。
  对于一个数据,如果无法在规定的条件救醒pige,请输出“-1”。

Hint


 30%,n <= 5;
 100%,n <= 500。

Analysis


好久好久好久好久好久以前的位运算搜索
位运算极其重要,要好好学习
             —来自AJ
           

然后我就放到了今天(┬_┬)

咳咳,严肃严肃
从全为1的起点开始bfs,直接用桶判重+步数记录
然后对于每个答案 O(1) 出解

深度只有6,随便搞都可以

数组要开short不然会MLE

Code


#include <stdio.h>
#include <string.h>
#include <queue>
#define lim (1<<25)-1
#define n 5
using namespace std;
queue<int>q;
short ans[lim+1];
char s[5];
int get(int x,int y)
{
    return (x-1)*n+y-1;
}
void bfs()
{
    q.push(lim);
    ans[lim]=1;
    while (!q.empty())
    {
        int now=q.front();q.pop();
        if (ans[now]+1<=7)
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++)
                {
                    int tmp=now;
                    tmp^=1<<get(i,j);
                    if (i>1)
                        tmp^=1<<get(i-1,j);
                    if (i<n)
                        tmp^=1<<get(i+1,j);
                    if (j>1)
                        tmp^=1<<get(i,j-1);
                    if (j<n)
                        tmp^=1<<get(i,j+1);
                    if (!ans[tmp])
                    {
                        ans[tmp]=ans[now]+1;
                        q.push(tmp);
                    }
                }
    }
}
int main()
{
    bfs();
    int t;
    scanf("%d",&t);
    for (int i=1;i<=t;i++)
    {
        int st=0;
        for (int i=1;i<=n;i++)
        {
            scanf("%s",s);
            for (int j=1;j<=n;j++)
                st|=(s[j-1]-'0')<<get(i,j);
        }
        printf("%d\n",ans[st]-1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值