codeforce 78E

思路:

先用BFS找出炸弹到各个地方的时间

再用BFS依次找出每个人(从它所在坐标 )在规定时间内能走到的所有坐标,以及到相应位置的时间
然后比较每个坐标,比较人所到的时间和炸弹到的时间,前者要比后者小才能通过,看这些合格的点中有没有救生胶囊,有的话就OK(这里的处理我代码上还有错,等有时间再改。。)


正规的做法是先用BFS建图,然后用最大流计算


#include <stdio.h>
#include <queue>
#include <string.h>
#include <iostream>
#include <memory.h>

using namespace std;

#define mp make_pair
typedef pair<int, int> pii;

int resc1[11][11];
int suv = 0;
int scie1[11][11];

char scie[11][11], resc[11][11];
int dist[11][11];
int seen[11][11];
int g[910][910];

int resccnt[11][11];
int sciecnt, ct;

int vis[1000];


int n, t;



const int INF = 10000;
queue<pii> fila;

void bfs(int dst[11][11])
{
    memset(seen, 0, sizeof(seen));
    pii rea = fila.front();
    dst[rea.first][rea.second] = 0;

    while(!fila.empty())
    {
        pii cur = fila.front();
        fila.pop();

        seen[cur.first][cur.second] = 1;

        for(int dx = -1; dx <= 1; dx++)
        {
            for(int dy = -1; dy <= 1; dy++)
            {
                if(dx + dy == 0 || dx * dy != 0)
                {
                    continue;
                }

                int nx = cur.first + dx, ny = cur.second + dy;

                if(nx < 0 || nx >= n || ny < 0 || ny >= n || scie[nx][ny] == 'Y' || seen[nx][ny])
                {
                    continue;
                }

                dst[nx][ny] = dst[cur.first][cur.second] + 1;

                if(dst == dist || dst[nx][ny] < dist[nx][ny])
                {
                    fila.push(mp(nx, ny));
                }
            }
        }
    }
}

void create(int x, int y)
{
    int mydist[11][11];

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            mydist[i][j] = INF;
        }
    }

    mydist[x][y] = 0;
    fila.push(mp(x, y));
    bfs(mydist);


    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {

            if(mydist[i][j] <= min(t, dist[i][j]) && scie[i][j] != 'Y' && scie[i][j] != 'Z')
            {


                if(resc1[i][j] > 0 && scie1[x][y]>0)
                {
                    if(scie1[x][y]<=resc1[i][j]){
                        suv += scie1[x][y] ;
                        resc1[i][j] -= scie[x][y]-'0';
                        scie1[x][y] -= scie[x][y]-'0';
                        return;

                    }else{

                        suv +=  resc1[i][j];
                        scie1[x][y] -= resc1[i][j];
                        resc1[i][j] = 0;

                    }

                }

            }
        }

    }


}

int main()
{
    scanf("%d %d", &n, &t);

    for(int i = 0; i < n; i++)
    {
        scanf("%s", scie[i]);
    }

    for(int i = 0; i < n; i++)
    {
        scanf("%s", resc[i]);
    }

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            dist[i][j] = INF;

            if(scie[i][j] == 'Z')
            {
                fila.push(mp(i, j));
            }
        }
    }

    bfs(dist);

    memset(resc1, 0, sizeof(resc1));
    memset(scie1, 0, sizeof(resc1));

    ct = 0;

    for(int i = 0; i < n; i++)     //record sum of resc point == 1+5
    {
        for(int j = 0; j < n; j++)
        {
            resccnt[i][j] = ct;

            if(resc[i][j] > '0' && resc[i][j] <= '9')
            {
                ct += resc[i][j] - '0';
                resc1[i][j] = resc[i][j] - '0';
            }

            if(scie[i][j] > '0' && scie[i][j] <= '9'){
                scie1[i][j] = scie[i][j] - '0';
            }


        }
    }



    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(scie[i][j] > '0' && scie[i][j] <= '9')
            {
                create(i, j);
            }
        }
    }




    cout << suv << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值