zoukankan      html  css  js  c++  java
  • light oj 1066- Gathering Food (bfs)

    H - Gathering Food
    Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu
    Appoint description: 

    Description

    Winter is approaching! The weather is getting colder and days are becoming shorter. The animals take different measures to adjust themselves during this season.

    - Some of them "migrate." This means they travel to other places where the weather is warmer.

    - Few animals remain and stay active in the winter.

    - Some animals "hibernate" for all of the winter. This is a very deep sleep. The animal's body temperature drops, and its heartbeat and breathing slow down. In the fall, these animals get ready for winter by eating extra food and storing it as body fat.

    For this problem, we are interested in the 3rd example and we will be focusing on 'Yogi Bear'.

    Yogi Bear is in the middle of some forest. The forest can be modeled as a square grid of size N x N. Each cell of the grid consists of one of the following.

    .           an empty space

    #         an obstacle

    [A-Z]  an English alphabet

    There will be at least 1 alphabet and all the letters in the grid will be distinct. If there are k letters, then it will be from the first k alphabets. Supposek = 3, that means there will be exactly one A, one B and one C.

    The letters actually represent foods lying on the ground. Yogi starts from position 'A' and sets off with a basket in the hope of collecting all other foods. Yogi can move to a cell if it shares an edge with the current one. For some superstitious reason, Yogi decides to collect all the foods in order. That is, he first collects A, then B, then C and so on until he reaches the food with the highest alphabet value. Another philosophy he follows is that if he lands on a particular food he must collect it.

    Help Yogi to collect all the foods in minimum number of moves so that he can have a long sleep in the winter.

    Input

    Input starts with an integer T (≤ 200), denoting the number of test cases.

    Each case contains a blank line and an integer N (0 < N < 11), the size of the grid. Each of the next N lines contains N characters each.

    Output

    For each case, output the case number first. If it's impossible to collect all the foods, output 'Impossible'. Otherwise, print the shortest distance.

    Sample Input

    4

    5

    A....

    ####.

    ..B..

    .####

    C.DE.

    2

    AC

    .B

    2

    A#

    #B

    3

    A.C

    ##.

    B..

    Sample Output

    Case 1: 15

    Case 2: 3

    Case 3: Impossible

    Case 4: Impossible

    bfs

    有从A开始的k种食物,每种食物只有一份。

    要求按照顺序吃,而且到达一个网格如果有食物必须吃掉,问能否按照顺序吃完,如果能,输出最短步数。

    一开始只做了一遍 bfs,找到b之后找c,但是可能的情况是一开始我先遇到c,但是这个时候我还没有吃到b,等吃到b以后,c附近的路径已经做了标记不能被拓展到了。

    取消标记? 当然不。。。会死循环。

    每吃到一个食物取消全部标记? 

    sounds good,但是我是直接用d数组判断是否访问过

    取消标记的话会把距离也取消掉。

    可以再开个布尔数组用来标记,d数组就专心记录距离,或者每次遇到食物把d数组的值累加到全局变量上也行。

    终止条件是,找到最后一个字母。

    我就不说因为把memset(d,-1,sizeof(d))写成memset(d,-1,sizeof(-1))wa 到死这种傻逼事了。。。。。

    /*************************************************************************
        > File Name: code/loj/1066.cpp
        > Author: 111qqz
        > Email: rkz2013@126.com 
        > Created Time: 2015年08月11日 星期二 18时30分39秒
     ************************************************************************/
    
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #include<stack>
    #define y0 abc111qqz
    #define y1 hust111qqz
    #define yn hez111qqz
    #define j1 cute111qqz
    #define tm crazy111qqz
    #define lr dying111qqz
    using namespace std;
    #define REP(i, n) for (int i=0;i<int(n);++i)  
    typedef long long LL;
    typedef unsigned long long ULL;
    const int inf = 0x7fffffff;
    const int N=13;
    int sx,sy;
    int n;
    char maze[N][N];
    int d[N][N];
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};
    int ans;
    int seek[N][N];
    int cnt;
    bool v[N][N];
    
    int bfs(int xx,int yy,char ch)
    {
        memset(d,-1,sizeof(-1)); 
        queue<int>x;
        queue<int>y;
        x.push(xx);
        y.push(yy);
        d[xx][yy] = 0;
        maze[xx][yy]='.';
        while (!x.empty())
        {
    
        int px = x.front();x.pop();
        int py = y.front();y.pop();
    //    cout<<"px:"<<px<<" py:"<<py<<endl;
        if (maze[px][py]==ch)
        {
            sx = px;
            sy = py;
            return d[px][py];
        }
        for ( int i = 0 ; i< 4 ; i++ )
        {
            int nx = px + dx[i];
            int ny = py + dy[i];
            if (nx>=0&&nx<n&&ny>=0&&ny<n&&d[nx][ny]==-1&&(maze[nx][ny]=='.'||maze[nx][ny]==ch))
            {
            
            d[nx][ny] =  d[px][py] + 1;
            x.push(nx);
            y.push(ny);
    
            }
        }
        }
        return -1;
    }
    int main()
    {
        int T;
        cin>>T;
        int cas = 0 ;
        while ( T-- )
        {
        cas++;
        ans = 0;
        scanf("%d",&n);
        for ( int i = 0 ; i  < n ; i++ )
        {
            scanf("%s",maze[i]);
        }
         cnt = 0 ;// 统计食物的数量
        for ( int i = 0 ; i < n ; i++ )
        {
            for ( int j = 0 ; j < n ; j ++)
            {
            if (maze[i][j]=='A')
            {
                sx = i ;
                sy = j;
            }
            if (maze[i][j]!='#'&&maze[i][j]!='.')
            {
                cnt++;
            }
            }
        }
        memset(d,-1,sizeof(d));
        d[sx][sy]  = 0;
        bool flag = false;
        for ( int i = 0 ; i < cnt ; i++ )
        {
            int tmp = bfs(sx,sy,char(i+'A'));
         //  cout<<"tmp:"<<tmp<<endl;
            if (tmp==-1)
            {
            flag = true;
            break;
            }
            ans += tmp;
    //        cout<<"tmp:"<<tmp<<" ans:"<<ans<<endl;
            
        }
    //    for ( int i = 0 ; i < n ; i++ )
    //    {
    //        for ( int j = 0 ; j < n ; j++ )
    //        {
    //        cout<<d[i][j]<<" ";
    //        }
    //        cout<<endl;
    //    }
        if (flag)
        {
    
            printf("Case %d: %d
    ", cas, ans);
        }
        else
        {
    
                printf("Case %d: Impossible
    ", cas);
        }
        }
      
        return 0;
    } 
  • 相关阅读:
    电子电路基础复习 —— 电阻
    Linux 网络编程(IO模型)
    Linux 2.6 源码学习-内存管理-buddy算法
    【转】MySQL性能优化的21个最佳实践
    linux 2.6 驱动笔记(三)
    linux 2.6 驱动笔记(二)
    公共代码参考(httpclient)
    linux 2.6 驱动笔记(一)
    bzoj 2401: 陶陶的难题I 数论
    bzoj 3144: [Hnoi2013]切糕 最小割
  • 原文地址:https://www.cnblogs.com/111qqz/p/4722788.html
Copyright © 2011-2022 走看看