uvalive 6888 Ricochet Robots bfs

题目链接

给一个n*m的图, 图上有n个标号, n<=4, 然后有墙, 还有一个终点x。 每一步, 只能走某一个标号, 可以向四个方向走, 然后必须要碰到墙或者图的边界或者另一个标号才能停下来。 问你在t步之内能否使第一个标号到达终点。

因为有一个上限t。 所以直接bfs就可以, 感觉思路不是很难, 但是写代码+调试花了超级久...不过总算1A, 不然就懵逼了。

#include <bits/stdc++.h>

using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<11
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 7777777;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
struct node
{
    vector<pll> a;
    int step;
    node() {
        step = 0;
    }
};
int cnt, w, h;
map <vector<pll>, int> mp;
vector <int> row[11], col[11];
pll target;
char s[11][11];
int bfs(const node& init, int t)
{
    queue <node> q;
    q.push(init);
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(tmp.step > t)
            continue;
        if(tmp.a[0] == target) {
            return tmp.step;
        }
        for(int i = 0; i < cnt; i++) {
            int x = tmp.a[i].fi, y = tmp.a[i].se;
            int tmpy = *(--lower_bound(row[x].begin(), row[x].end(), y));
            for(int j = 0; j < cnt; j++) {
                if(i == j)
                    continue;
                if(tmp.a[i].fi == tmp.a[j].fi && tmp.a[i].se > tmp.a[j].se) {
                    tmpy = max(tmpy, tmp.a[j].se);
                }
            }
            tmpy++;
            vector<pll> ha(tmp.a);
            ha[i].se = tmpy;
            if(!mp[ha]) {
                node newNode = tmp;
                newNode.a[i].se = tmpy;
                newNode.step++;
                q.push(newNode);
                mp[ha] = 1;
            }

            x = tmp.a[i].fi, y = tmp.a[i].se;
            tmpy = *lower_bound(row[x].begin(), row[x].end(), y);
            for(int j = 0; j < cnt; j++) {
                if(i == j)
                    continue;
                if(tmp.a[i].fi == tmp.a[j].fi && tmp.a[i].se < tmp.a[j].se) {
                    tmpy = min(tmpy, tmp.a[j].se);
                }
            }
            tmpy--;
            ha = tmp.a;
            ha[i].se = tmpy;
            if(!mp[ha]) {
                node newNode = tmp;
                newNode.a[i].se = tmpy;
                newNode.step++;
                mp[ha] = 1;
                q.push(newNode);
            }

            x = tmp.a[i].fi, y = tmp.a[i].se;
            int tmpx = *(--lower_bound(col[y].begin(), col[y].end(), x));
            for(int j = 0; j < cnt; j++) {
                if(i == j)
                    continue;
                if(tmp.a[i].se == tmp.a[j].se && tmp.a[i].fi > tmp.a[j].fi) {
                    tmpx = max(tmpx, tmp.a[j].fi);
                }
            }
            tmpx++;
            ha = tmp.a;
            ha[i].fi = tmpx;
            if(!mp[ha]) {
                node newNode = tmp;
                newNode.a[i].fi = tmpx;
                newNode.step++;
                q.push(newNode);
                mp[ha] = 1;
            }
            x = tmp.a[i].fi, y = tmp.a[i].se;
            tmpx = *lower_bound(col[y].begin(), col[y].end(), x);
            for(int j = 0; j < cnt; j++) {
                if(i == j)
                    continue;
                if(tmp.a[i].se == tmp.a[j].se && tmp.a[i].fi < tmp.a[j].fi) {
                    tmpx = min(tmpx, tmp.a[j].fi);
                }
            }
            tmpx--;
            ha = tmp.a;
            ha[i].fi = tmpx;
            if(!mp[ha]) {
                node newNode = tmp;
                newNode.a[i].fi = tmpx;
                newNode.step++;
                q.push(newNode);
                mp[ha] = 1;
            }
        }
    }
    return -1;
}
int main()
{
    int t;
    while(cin>>cnt>>w>>h>>t) {
        mp.clear();
        for(int i = 0; i < h; i++) {
            scanf("%s", s[i]);
        }
        for(int i = 0; i < h; i++) {
            row[i].clear();
            row[i].pb(-1);
            row[i].pb(w);
        }
        for(int i = 0; i < w; i++) {
            col[i].clear();
            col[i].pb(-1);
            col[i].pb(h);
        }
        node init;
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(s[i][j] == ‘X‘)
                    target = mk(i, j);
                if(s[i][j] == ‘W‘) {
                    row[i].pb(j);
                    col[j].pb(i);
                }
            }
        }
        for(int i = 1; i <= cnt; i++) {
            for(int j = 0; j < h; j++) {
                for(int k = 0; k < w; k++) {
                    if(s[j][k]-‘0‘ == i) {
                        init.a.pb(mk(j, k));
                    }
                }
            }
        }
        for(int i = 0; i < h; i++) {
            sort(row[i].begin(), row[i].end());
        }
        for(int i = 0; i < w; i++)
            sort(col[i].begin(), col[i].end());
        mp[init.a] = 1;
        int ans = bfs(init, t);
        if(ans == -1) {
            puts("NO SOLUTION");
        } else {
            cout<<ans<<endl;
        }
    }
}
时间: 2024-12-06 21:00:21

uvalive 6888 Ricochet Robots bfs的相关文章

UVALive 5066 Fire Drill BFS+背包

H - Fire Drill Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 5066 Description Joko is taking part in a fire drill which is held by the Jakarta Fire Department to recruit new firemen. The drill i

UVALive 4025 Color Squares(BFS)

题目链接:UVALive 4025 Color Squares 按题意要求涂色,求达到w分的最少步数. //yy:哇,看别人存下整个棋盘的状态来做,我什么都不想说了,不知道下午自己写了些什么东西,训练结束补的.. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define CLR(a, b) memset((a),(b),sizeof

UVALive 5066 Fire Drill --BFS+DP

题意:有一个三维的地图,有n个人被困住,现在消防队员只能从1楼的一个入口进入,营救被困者,每一个被困者有一个价值,当消防队员找到一个被困者之后,他可以营救或者见死不救,如果救的话,他必须马上将其背到入口处,不得停下,不得同时救多个人,而且回去的时间一步要做两步走,即时间增加一倍.求在给定时间S内,能救到的人的最大价值总和. 解法:bfs一遍记录每个点离起点的最短距离,那么救这个人的花费就是3*dis,然后已经知道救这个人的价值,那么最后求一个01背包即可. 要注意一个人都救不到的地方,我开始将d

UVALive 6663 Count the Regions 离散+bfs染色_(:зゝ∠)_

题目链接:点击打开链接 gg..== #include <cstdio> #include <cstring> #include<iostream> #include <queue> #include <set> #include <map> #include <algorithm> #include <string> using namespace std; #define ll long long #def

UVALive 6665 Dragon&#226;??s Cruller --BFS,类八数码问题

题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue&g

UVALive - 6455 Stealing Harry Potter&#39;s Precious (bfs+dfs)

https://cn.vjudge.net/problem/UVALive-6455 题目大意:题目上给出一个地图,其中@是人在地图上的出发点,#是墙,' . '是路.然后给出几个点,这些点表示财宝的所在地.问人是否能够得到所有的宝藏,如果能够的话给出所有的宝藏的最短的路径. 解题思路:由于只有最多4个宝藏所在地,所以只要用bfs找出出发点和财宝所在地距离到达其他点的步数.因为最多只有4个宝藏,所以可以暴力找出出发点到所有宝藏的最短距离. 暴力代码: 1 #include<stdio.h> 2

UVALive 3977 BFS染色

这个题意搞了半天才搞明白 就是如果定义一个d-summit,即从该点到另一个更高的点,经过的路径必定是比当前点低至少d高度的,如果该点是最高点,没有比他更高的,就直接视为顶点 其实就是个BFS染色,先按降序排序,然后每个点对其可到达的点染色,h-d的点为边界,走到这里就不用往下染了 然后其他店染色的时候若产生冲突,则非d—summit,否则该点为顶点 今天还有COJ上一个BFS染色的题目,一直TLE...还没弄出来 #include <iostream> #include <cstdio

UVALive 7297 bfs

题意 一个小偷偷到了项链 他想知道自己是否可以逃出去 地图中有一个小偷 一个警察 警察有一条狗 一开始 小偷和警察的移动速度都是1 当警察走到小偷经过过的地方时 警察会有一条狗嗅到小偷的气味并且以2的速度去追 由于问题问的是 小偷是否必定有方法逃出 所以我们可以看作 有无限个警察从一个点出发去抓小偷 每经过一个点 这个点上就会有一个警察站着 所以会有一个limit来记录警察到达这个点的最短的时间 我们可以想到 小偷到这个点的时间和警察到达这个点的时间的差 就是小偷到这个点之后可以行动的时间(如果

UVALive 7297 Hounded by Indecision BFS

题目链接:Hounded by Indecision 题意:map中给出小偷的位置,警察的位置.警察有一只狗,开始的时候警察和狗一起行动,也就是看做一个格子,当警察遇见小偷走过的格子时,狗就会嗅到它的气味,以2倍的速度追捕小偷.现在,小偷希望知道自己是否有安全路线逃出去,以此决定是否要继续拿着偷的东西.出口不止一处,只有一个警察和一只狗,一个小偷.[知道也才不告诉他,哼.] 思路:因为小偷每走到一个格子时,时间为t1,决定他是否被抓到的因素是警察到这里的时间t2.当t1>=t2时,小偷被抓,当t