校OJ P1220 -- zyf的现状


今天通关zyf全家桶了,发个博客记录一下

这题是一道bfs,开始用的普通队列,一直WA,百思不得其解,问了一下少颖学长才明白这一题应该用优先队列,因为移动消耗不全为1

思路就是以s -> 1, 1 -> 2......n-1-> E的顺序进行BFS

下面上丑陋的代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cctype>
#include <map>
using namespace std;

const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
const int maxn = 15+2;
int x[maxn], y[maxn];
int n, m, ans, p;
char maps[maxn][maxn];
bool vis[maxn][maxn];
map<char,int> cost;

struct Point{
    int x, y, s;
    Point( int a, int b, int c ) : x(a), y(b), s(c) {};
    bool operator < ( Point a ) const { return s > a.s; }
};

int scan() {
    int rec = 0;
    char ch;
    while( (ch = getchar()) ) {
        if( ch == '*' ) return -1;
        if( ch == 'S' ) return 0;
        if( ch == 'E' ) return 15;
        if( isdigit(ch) ) break;
    }
    rec += ch - '0';
    while( ( isdigit(ch = getchar()) ) ) {
        rec *= 10;
        rec += ch - '0';
    }
    return rec;
}

void init() {
    ans = 0;
    p = 0;
}

int bfs( int sx, int sy, int ex, int ey ) {
    priority_queue<Point> que;
    bool isget = false;
    que.push(Point(sx,sy,0));
    vis[sx][sy] = 1;
    while( !que.empty() && !isget ) {
        Point cur = que.top(); que.pop();
        int nx = cur.x, ny = cur.y, ns = cur.s;
        for( int i = 0; i < 4; i++ ) {
            int tx = nx + dx[i], ty = ny + dy[i];
            if( tx < 1 || ty < 1 || tx > n || ty > m ) continue;
            if( vis[tx][ty] || maps[tx][ty] == 'X' ) continue;
            vis[tx][ty] = 1;
            if( tx == ex && ty == ey ) {
                isget = 1;
                ans += ns + cost[maps[tx][ty]];
                break;
            }
            else
                que.push( Point(tx, ty, ns+cost[maps[tx][ty]] ) );
        }
    }
    memset(vis, 0, sizeof(vis));
    while(!que.empty()) que.pop();
}

void input() {
    int t1, t2, t3;
    char t;
    cin >> n >> m;
    for( int i = 1; i <= n; i++ )
        for( int j = 1; j <= m; j++ )
            cin >> maps[i][j];
    while( true ) {
        t1 = scan();
        if( t1 == -1 ) break;
        t2 = scan(); t3 = scan();
        if( t1 == 0 || t1 == 15 ) p--;
        p++;
        x[t1] = t2; y [t1] = t3;
    }
    x[p+1] = x[15]; y[p+1] = y[15];
    //用p来记录中间要通过多少个点,用0来储存起点,用15来临时储存终点,之后放在最末端
}

void solve() {
    for( int i = 0; i <= p; i++ )
        bfs( x[i], y[i], x[i+1], y[i+1] );
}

int main() {
    cost['0'] = 1;
    cost['#'] = 2;
    cost['T'] = 4;
    int T;
    cin >> T;
    while(T--) {
        init();
        input();
        solve();
        cout << ans << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值