搜索题目:

bfs+位压缩:

hdu 1429 http://acm.hdu.edu.cn/showproblem.php?pid=1429

中文题目:

思路:bfs+位压缩

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout)


#define M 137
#define N 22

using namespace std;
const double eps = 1e-10;

struct node
{
    int x,y;
    int val;
    int msk;//一共10为来表示到达某点时所拥有的钥匙种类
    bool operator < (const node &a) const
    {
        return val > a.val;
    }
}nd;

priority_queue<node>Q;
int sx,sy,ex,ey;

char mat[N][N];
int n,m,k;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
bool vt[N][N][1028];//由于是优先队列处理所以只要到达该点就是最优的

int bfs(int x,int y)
{
    CL(vt,false);
    while (!Q.empty()) Q.pop();
    nd.x = x; nd.y = y;
    nd.val = 0; nd.msk = 0;
    Q.push(nd);
    vt[x][y][nd.msk] = true;
    while (!Q.empty())
    {
        node u = Q.top(); Q.pop();
        for (int i = 0; i < 4; ++i)
        {
            int tx = u.x + dx[i];
            int ty  =u.y + dy[i];
            int val = u.val + 1;
            int msk = u.msk;

            if (val >= k) continue;

            if (tx >= 0 && tx < n && ty >= 0 && ty < m && mat[tx][ty] != '*' && !vt[tx][ty][msk])
            {
                nd.x = tx; nd.y = ty;
                nd.val = val; nd.msk = msk;
                if (mat[tx][ty] == '.' || mat[tx][ty] == '@')
                {
                    vt[tx][ty][msk] = true;
                    Q.push(nd);
                }
                else if (mat[tx][ty] >= 'a' && mat[tx][ty] <= 'j')
                {
                    nd.msk = nd.msk | (1<<(mat[tx][ty] - 32 - 'A'));
                    vt[tx][ty][nd.msk] = true;
                    Q.push(nd);
                }
                else if (mat[tx][ty] >= 'A' && mat[tx][ty] <= 'J')
                {
                    if (u.msk & (1<<(mat[tx][ty] - 'A')))
                    {
                        vt[tx][ty][msk] = true;
                        Q.push(nd);
                    }
                }
                else if (mat[tx][ty] == '^')
                {
                    return nd.val;
                }
            }
        }
    }
    return -1;
}
int main()
{
//    Read();
    int i,j;
    while (~scanf("%d%d%d",&n,&m,&k))
    {
        for (i = 0; i < n; ++i)
        {
            scanf("%s",mat[i]);
            for (j = 0; j < m; ++j)
            {
                if (mat[i][j] == '@')
                {
                    sx = i; sy = j;
                }
            }
        }
        printf("%d\n", bfs(sx,sy));
    }
    return 0;
}
View Code

 

 hdu 1885 Key Task

http://acm.hdu.edu.cn/showproblem.php?pid=1885

题意:

给你一个n*m的矩形迷宫,里面有 起点* 多个出口X,墙#  还有一些门 B,Y,R,G  ,只有拥有了 钥匙 b,y,r,g才能打开门然后继续往下走。求能够走出迷宫的最小步数(只要走到任意一个出口即可)

思路:

bfs+位压缩

bfs找最少步数,位压缩记录到达某个点时所拥有的钥匙

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 20010
#define N 110
using namespace std;
const int mod = 1000000007;

int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};

struct node
{
    int x,y;
    int ds;
    int msk;
}nd;

char mat[N][N];

bool vt[N][N][20];
int n,m;
int sx,sy;
int ans;

int getR(char c)
{
    if (c == 'b') return 0;
    if (c == 'y') return 1;
    if (c == 'r') return 2;
    return 3;
}
bool inmap(int x,int y)
{
    if (x >= 0 && x < n && y >= 0 && y < m && mat[x][y] != '#') return true;
    return false;
}
bool isKey(char c)
{
    if (c == 'b' || c == 'y' || c == 'r' || c == 'g') return true;
    return false;
}
bool isFree(char c)
{
    if (c == '.' || c == '*') return true;
    return false;
}
bool isDoor(char c)
{
    if (c == 'B' || c == 'Y' || c == 'R' || c == 'G') return true;
    return false;
}
int bfs(int x,int y)
{
    nd.x = x; nd.y = y;
    nd.ds = 0; nd.msk = 0;

    queue<node>Q;
    Q.push(nd);

    CL(vt,false);
    vt[sx][sy][0] = true;

    while (!Q.empty())
    {
        nd = Q.front(); Q.pop();
        for (int i = 0; i < 4; ++i)
        {
            int tx = nd.x + dx[i];
            int ty = nd.y + dy[i];
            int ds = nd.ds + 1;
            int msk = nd.msk;

            if (inmap(tx,ty))
            {
                if (mat[tx][ty] == 'X')
                {
                    ans = ds;
                    return 1;
                }
                node tmp;
                tmp.x = tx; tmp.y = ty;
                tmp.ds = ds;

                if (isKey(mat[tx][ty]))
                {
                    msk |= (1<<(getR(mat[tx][ty])));
                    tmp.msk = msk;
                    if (!vt[tx][ty][msk])
                    {
                        vt[tx][ty][msk] = true;
                        Q.push(tmp);
                    }
                }
                else if (isFree(mat[tx][ty]))
                {
                    if (!vt[tx][ty][msk])
                    {
                        tmp.msk = msk;
                        vt[tx][ty][msk] = true;
                        Q.push(tmp);
                    }
                }
                else if (isDoor(mat[tx][ty]) && (msk&(1<<getR(mat[tx][ty] + 32))))
                {
                    if (!vt[tx][ty][msk])
                    {
                        tmp.msk = msk;
                        vt[tx][ty][msk] = true;
                        Q.push(tmp);
                    }
                }
            }
        }
    }
    return 0;
}
int main()
{
//    Read();
    int i,j;
    while (~scanf("%d%d",&n,&m))
    {
        if (!n && !m) break;

        bool flag = false;
        sx = sy = -1;
        for (i = 0; i < n; ++i)
        {
            scanf("%s",mat[i]);
            for (j = 0; j < m; ++j)
            {
                if (mat[i][j] == '*')
                {
                    sx = i; sy = j;
                }
                if (mat[i][j] == 'X')
                {
                    flag = true;
                }
            }
        }
        if (!flag || sx == -1)
        {
            printf("The poor student is trapped!\n");
            continue;
        }
        ans = -1;
//        printf(">>>>%d %d\n",sx,sy);
        bfs(sx,sy);
        if (ans != -1) printf("Escape possible in %d steps.\n",ans);
        else printf("The poor student is trapped!\n");
    }
    return 0;
}
View Code

 

 <------------------------------------------------------------------------------------------------------------->

hdu 1226 超级密码

题意:中文

思路:
首先我们要知道这样一个原理:

r%c = k%c  ==> (r*p + a) = (k*p + a);

证明:

形式证明.....r=k(mod c)-> k= q*c+r ->  (k*p+a)=((q*c+r)*p+a)=p*q*c+p*r+a -> (k*p+a) (mod c) = (r*p+a) (mod c) 

(注:由于p*q*c中含有因子c,所以取模后=0.........)

所以我们要求组和出来的这个数的c进制数能够整除n,只要求组和出来的这个数对n取余,余数为0的情况是最小的数即可。

当我们组合出来的的数x对n取余后为y时,如果我们继续在后面添加数的(x*c + p) %n 仍然等于y而此时这个数的长度增加了,必定变大了。 所以我们只要对余数搜索,达到这个余数时的最小的数即可。  bfs来保证组和的这个数长度最短,然后从小打到枚举这m个数,就能够保证出现余数为0时即为最小。

这里有一个trick就是当n为0,时假设m个数里面有0也存在正确答案

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout)


#define M 137
#define N 5007
#define ll __int64
using namespace std;
const double eps = 1e-10;

struct node
{
    int len;
    int num[507];
    int rem;
}nd;

int vt[N];
bool ok[20];
int n,c,m;

int getR(node a)
{
    int sum = 0;
    for (int i = 1; i <= a.len; ++i)
    {
        sum = (sum*c%n + a.num[i])%n;
    }
    return sum;
}
void print(node a)
{
    for (int i = 1; i < a.len; ++i)
    printf("%X",a.num[i]);
    printf("%X\n",a.num[a.len]);
}
void bfs()
{
    CL(vt,false);
    queue<node>Q;
    for (int i = 1; i <= 16; ++i)
    {
        if (!ok[i]) continue;

        nd.len = 1;
        nd.num[nd.len] = i;
        nd.rem = getR(nd);
        if (nd.rem == 0)
        {
            print(nd);
            return ;
        }
        if (!vt[nd.rem])
        {
            vt[nd.rem] = true;
            Q.push(nd);
        }
    }
    while (!Q.empty())
    {
        nd = Q.front(); Q.pop();
        for (int i = 0; i <= 16; ++i)
        {
            if (!ok[i]) continue;

            node tmp = nd;
            tmp.len = nd.len + 1;
            if (tmp.len > 500) break;
            tmp.num[tmp.len] = i;
            tmp.rem = getR(tmp);
            if (tmp.rem == 0)
            {
                print(tmp);
                return ;
            }
            if (!vt[tmp.rem])
            {
                vt[tmp.rem] = true;
                Q.push(tmp);
            }
        }
    }
    printf("give me the bomb please\n");
}
int main()
{
//    Read();
    int T,i;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&c);
        scanf("%d",&m);
        CL(ok,false);
        int x;
        for (i = 0; i < m; ++i)
        {
            scanf("%x",&x);
            //测试用输入数据保证合法,
//            if (x >= c)
//            {
//                printf("NIMASHUJUBUDUI");
//            }
            ok[x] = true;
        }

        if (n == 0)
        {
            if (ok[0]) printf("0\n");
            else printf("give me the bomb please\n");
            continue;
        }
        bfs();
    }
    return 0;
}
View Code

 

 hdu 1664 Different Digits

题意:

给你一个数n,求一个数m,使得m满足1:是n的倍数,2:所含不同的数字数目最少

思路:

首先我们可以根据鸽巢定理得知,存在n+1个数,使得其中肯定存在两个数的与n同余。即x%n = y%n 则abs(x - y)%n == 0   应为要使m所含不同的数字最少,所以我们假设这n+1个数形如0,a,aa,aaa,aaaa ...... aaaaaaaa(n个a) 他们存在两个数相减为n的倍数,那么这个数要么含有一个数字 例如2222 - 1111 = 1111   要么含有两个数字3333 - 11 = 3322

我们只要分别讨论即可,而且这个数的长度肯定不会超过n,模n的状态也不会超过n,当有一个时,我们只要枚举9个数字,然后枚举长度即可。当存在两个时,我们枚举这两数字,然后利用bfs保存模n的状态寻找结果求出最优即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val) memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("d.out", "w", stdout)
#define ll unsigned long long


#define M 100007
#define N 65736

using namespace std;

const int inf = 0x7f7f7f7f;
const int mod = 1000000007;

struct node
{
    int val;
    int pre;
}nd[N];
int n;

int solve1(int a)
{
    int s = 0;
    for (int i = 1; i <= n; ++i)
    {
        s = (s*10%n + a)%n;
        if (s == 0) return i;
    }
    return 0;
}
string solve2(int a[])
{
    for (int i = 0; i <= n; ++i) nd[i].pre = -1, nd[i].val  = 0;
    queue<int>q;
    q.push(0);
    bool flag = true;

    while (!q.empty())
    {
        int u = q.front(); q.pop();
        for (int i = 0; i < 2; ++i)
        {
            if (flag && !a[i]) continue;
            flag = false;
            int tmp = (u*10%n + a[i])%n;
            if (tmp == 0)
            {
                string ans = ""; ans += a[i] + '0';
                while (u)
                {
                    ans += nd[u].val + '0';
                    u = nd[u].pre;
                }
                while (ans.size() != n) ans += '0';
                reverse(ans.begin(),ans.end());

                return ans;
            }
            if (nd[tmp].pre == -1)
            {
                nd[tmp].pre = u;
                nd[tmp].val = a[i];
                q.push(tmp);
            }
        }
    }
    return string(n,'9');
}
int main()
{
   while (~scanf("%d",&n))
   {
       if (!n) break;
       int res = n + 1;
       int c = 0;
       for (int i = 1; i < 10; ++i)
       {
           int tmp = solve1(i);
           if (tmp && tmp < res) res = tmp,c = i;
       }
       if (res != n + 1)
       {
           for (int i = 0; i < res; ++i) printf("%d",c);
           printf("\n");
       }
       else
       {
           int a[2];
           string ans = string(n,'9');

           for (a[0] = 0; a[0] < 10; ++a[0])
           {
               for (a[1] = a[0] + 1; a[1] < 10; ++a[1])
               {
                   string tmp = solve2(a);
//                   cout<<"TMP = " << tmp <<endl;
                   if (tmp < ans) ans = tmp;
               }
           }
           size_t i = 0;
           while (ans[i] == '0') i++;
           for (; i < ans.size(); ++i) printf("%c",ans[i]);
           printf("\n");
       }
   }
   return 0;
}
View Code

 

 hdu 2821 Pusher

题意:

给你一个关系矩阵,其中'.'表示空地,'a' - 'z'表示有多少个箱子 'a' = 1, 'b' = 2...., 任选一个起点(i,j),然后上下左右找箱子推,当某一方向有箱子p个时的时候他可以移动到该点(x,y)将一个箱子移出矩阵,剩下的累加到这一方向的下一个点。  注意这里当箱子在边界上的时候不能已送,  (i,j) 与 (x,y)必须满足中间至少有一个空格。

思路:

自己想了一个bfs的方法,不过写了200多行,感觉不对,然后就挂了。后来看了一下别人的,就不到100行解决了。哎,自己的思路还是不行啊。

注意我们可以一步一步的模拟的走,这样比较好处理,然后dfs往下走,我们每次移出一个箱子所以总的步数就是总的箱子个数。 然后记录每一步的操作即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll long long
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define keyTree (chd[chd[root][1]][0])
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 35
#define N 35

using namespace std;

const int inf = 0x7f7f7f7f;
const int mod = 1000000007;

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
char ans[20000];
int mat[N][M];
char str[N][M];
int n,m,s;
bool flag;
string mk = "UDLR";

bool inmap(int x,int y)
{
    return (x >= 0 && x < n && y >= 0 && y < m);
}
void dfs(int x,int y,int p)
{
    if (p >= s)
    {
        flag = true;
        return ;
    }
    if (flag) return ;
    for (int i = 0; i < 4 && !flag; ++i)//注意这里的!flag直接坑的我快死了,如果这一步没有当回溯时会影响ans,所以为了保证ans必须存在
    {
        int tx = x + dx[i];
        int ty = y + dy[i];
        if (!inmap(tx,ty) || mat[tx][ty]) continue;
        while (inmap(tx,ty) && !mat[tx][ty]) tx += dx[i],ty += dy[i];
        if (!inmap(tx + dx[i],ty + dy[i])) continue;
        int tmp = mat[tx][ty];
        mat[tx + dx[i]][ty + dy[i]] += (tmp - 1);
        mat[tx][ty] = 0;
        ans[p] = mk[i];
        dfs(tx,ty,p + 1);
        mat[tx + dx[i]][ty + dy[i]] -= (tmp - 1);
        mat[tx][ty] = tmp;
    }
}

int main()
{
//    Read();
    while (~scanf("%d%d",&m,&n))
    {
        s = 0;
        for (int i = 0; i < n; ++i)
        {
            scanf("%s",str[i]);
            for (int j = 0; j < m; ++j)
            {
                if (str[i][j] == '.') mat[i][j] = 0;
                else mat[i][j] = str[i][j] - 'a' + 1;

                s += mat[i][j];
            }
        }
        flag = false;
        for (int i = 0; i < n && !flag; ++i)
        {
            for (int j = 0; j < m && !flag; ++j)
            {
                if (mat[i][j] != 0) continue;
                dfs(i,j,0);
                if (flag)
                {
                    printf("%d\n%d\n",i,j);
                    for (int k = 0; k < s; ++k) printf("%c",ans[k]);
                    printf("\n");
                    break;
                }
            }
        }
    }
    return 0;
}
View Code

 

 hdu 2128 Tempter of the Bone II

题意:

给你一个关系矩阵,其中S代表起点,D代表终点,X代表墙,1-9代表有几个炸弹,。问某人是否能够从起点到达终点。如果不能输出-1否则输出最少的时间花费

思路:

因为涉及到最小问题,还是首先考虑bfs然后我们要记录每一个状态才开始把状态搞错了,调了好久。 我们这里的状态是记录哪些墙已经被炸开了,哪些地点的炸弹已经拿过了,所以我们应该以整张图为状态,因为该图最大即为8*8 = 64 所以我们可以利用它位压缩ull来保存整张图来表示唯一状态,然后就是模拟整个走的过程。优先队列处理一下遇到目标就是最优。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll long long
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define keyTree (chd[chd[root][1]][0])
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);

#define ULL unsigned long long
#define M 600
#define N 10

using namespace std;

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};

const int inf = 0x7f7f7f7f;
const int mod = 1000000007;


int n,m;
struct node
{
    int x,y;//
    int tm;//花费的时间
    int ep;//拥有的炸弹数
    ULL flag;//当前状态的整张图
    node(int xi,int yi,int tmi,int epi,ULL flagi)
    {
        x = xi; y = yi; tm = tmi;
        ep = epi; flag = flagi;
    }
    node(){}
    bool operator< (const node &b) const
    {
        return tm > b.tm;
    }
};

int sx,sy;
char str[N][N];
int ans;
bool flag;
map<ULL,int> vt[N][N];//map来记录到达该状态的最优质

bool inmap(int x,int y)
{
    return (x >= 0 && x < n && y >= 0 && y < m);
}
int bfs()
{
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            vt[i][j].clear();
        }
    }
    priority_queue<node> Q;
    Q.push(node(sx,sy,0,0,(ULL)0));
    vt[sx][sy][0] = 0;
    while (!Q.empty())
    {
        node u = Q.top(); Q.pop();
//        if (u.tm > vt[u.x][u.y][u.flag]) continue;

        if (str[u.x][u.y] == 'D') return u.tm;

        for (int i = 0; i < 4; ++i)
        {
            int tx = u.x + dx[i];
            int ty = u.y + dy[i];
            if (!inmap(tx,ty)) continue;

            int k = tx*m + ty;

            if (str[tx][ty] == 'X')
            {
                if (u.flag & ((ULL)1<<k))//已经炸开了
                {
                    map<ULL,int>::iterator it = vt[tx][ty].find(u.flag);
                    int num = (it == vt[tx][ty].end()) ? inf:it->second;
                    if (num > u.tm + 1)
                    {
                        vt[tx][ty][u.flag] = u.tm + 1;
                        Q.push(node(tx,ty,u.tm + 1,u.ep,u.flag));
                    }
                }
                else//未炸开
                {
                    map<ULL,int>::iterator it = vt[tx][ty].find(u.flag|((ULL)1<<k));
                    int num = (it == vt[tx][ty].end()) ? inf : it->second;
                    if (u.ep >= 1 && num > u.tm + 2)
                    {
                        vt[tx][ty][u.flag|((ULL)1<<k)] = u.tm + 2;
                        Q.push(node(tx,ty,u.tm + 2,u.ep - 1,u.flag|((ULL)1<<k)));
                    }
                }
            }
            else if (str[tx][ty] >= '0' && str[tx][ty] <= '9')
            {
                if (u.flag & ((ULL)1<<k))//已将取了
                {
                    map<ULL,int>::iterator it = vt[tx][ty].find(u.flag);
                    int num = (it == vt[tx][ty].end()) ? inf : it->second;
                    if (num > u.tm + 1)
                    {
                        vt[tx][ty][u.flag] = u.tm + 1;
                        Q.push(node(tx,ty,u.tm + 1,u.ep,u.flag));
                    }
                }
                else
                {
                    map<ULL,int>::iterator it = vt[tx][ty].find(u.flag|((ULL)1<<k));
                    int num = (it == vt[tx][ty].end()) ? inf : it->second;
                    if (num > u.tm + 1)
                    {
                        vt[tx][ty][u.flag|((ULL)1<<k)] = u.tm + 1;
                        Q.push(node(tx,ty,u.tm + 1,u.ep + str[tx][ty] - '0',u.flag|((ULL)1<<k)));
                    }
                }
            }
            else
            {
                map<ULL,int>::iterator it = vt[tx][ty].find(u.flag);
                int num = (it == vt[tx][ty].end()) ? inf : it->second;
                if (num > u.tm + 1)
                {
                    vt[tx][ty][u.flag] = u.tm + 1;
                    Q.push(node(tx,ty,u.tm + 1,u.ep,u.flag));
                }
            }

        }
    }
    return -1;
}
int main()
{
//    Read();
    while (~scanf("%d%d",&n,&m))
    {
        if (!n && !m) break;
        for (int i = 0; i < n; ++i)
        {
            scanf("%s",str[i]);
            for (int j = 0; j < m; ++j)
            {
                if (str[i][j] == 'S')
                {
                    sx = i,sy = j;
                }
            }
        }
        ans = bfs();
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 

posted @ 2013-05-30 13:49  E_star  阅读(279)  评论(0编辑  收藏  举报