bfs 2016.5.2

1、HDU 2612 Find a way

题意:

Y和M去KFC见面,有很多KFC,帮他们找一个KFC使得他们花费的时间总和最小

解题思路:

两次 bfs 分别找出他们到达他们都能到达的所有的KFC的最短时间

然后比较他们花费时间的和找出最小

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 200 + 5;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dis[maxn][maxn][2];
int dir[][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int n, m;

struct Node {
    int x, y;
    int Count;
};

void bfs(int i, int j, int y_m);

int main()
{
//    freopen("in.txt", "r", stdin);
    while (cin>>n>>m) {
        memset(dis, 0, sizeof(dis));
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                cin>>Map[i][j];
            }
        }
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                if (Map[i][j] == 'Y') {
                    memset(vis, false, sizeof(vis));
                    bfs(i, j, 0);
                }
                if (Map[i][j] == 'M') {
                    memset(vis, false, sizeof(vis));
                    bfs(i, j, 1);
                }
            }
        }
        int Min = INT_MAX;
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                if (Map[i][j] == '@') {
                    if (dis[i][j][0] > 0) {
                        int t = dis[i][j][0] + dis[i][j][1];
                        if (t < Min) {
                            Min = t;
                        }
                    }
                }
            }
        }
        cout<<Min*11<<endl;
    }
    return 0;
}

void bfs(int i, int j, int y_m)
{
    Node node;
    queue<Node> Queue;
    node.x = i;
    node.y = j;
    node.Count = 0;
    Queue.push(node);
    vis[i][j] = true;
    while (!Queue.empty()) {
        int nx = Queue.front().x;
        int ny = Queue.front().y;
        int nCount = Queue.front().Count;
        Queue.pop();
        for (int i=0; i<4; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            node.Count = nCount + 1;
            if ((node.x>=0) && (node.x<n) && (node.y>=0) && (node.y<m)) {
                if (Map[node.x][node.y]!='#' && !vis[node.x][node.y]) {
                    Queue.push(node);
                    vis[node.x][node.y] = true;
                    dis[node.x][node.y][y_m] = node.Count;
                }
            }
        }
    }
}

2、POJ 2312 Battle City

题意:

你的坦克每次每次可以进行两种操作,向四周的空地移动或者射击砖墙将它变成空地但是不移动

问到达目的地需要的最少操作次数

解题思路:

关键是要保证队列中的操作次数是递增的

一:

可以将射击砖墙不移动这个操作 改为 把砖墙当作“伪空地”然后移动到这个地方,以后若遇到“伪空地”则变成空地然后直接跳出循环

二、

优先队列

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

struct Node {
    int x, y;
    int Count;
};

int bfs(int a, int b);

int main()
{
//    freopen("in.txt", "r", stdin);
    while (cin>>M>>N && !(M==0&&N==0)) {
        memset(vis, false, sizeof(vis));
        int x, y;
        for (int i=0; i<M; ++i) {
            for (int j=0; j<N; ++j) {
                cin>>Map[i][j];
                if (Map[i][j] == 'Y') {
                    x = i;
                    y = j;
                }
            }
        }
        int least = bfs(x, y);
        cout<<least<<endl;
    }
    return 0;
}

int bfs(int a, int b)
{
    queue<Node> Queue;
    Node node;
    node.x = a;
    node.y = b;
    node.Count = 0;
    Queue.push(node);
    vis[a][b] = 1;
    while (!Queue.empty()) {
        int nx = Queue.front().x;
        int ny = Queue.front().y;
        int nCount = Queue.front().Count;
        Queue.pop();
        if (Map[nx][ny] == 'T') {
            return nCount;
        }
        if (Map[nx][ny] == 'B') {
            Map[nx][ny] = 'E';
            node.x = nx;
            node.y = ny;
            node.Count = nCount + 1;
            Queue.push(node);
            continue;
        }
        for (int i=0; i<4; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
                if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
                    node.Count = nCount + 1;
                    vis[node.x][node.y] = 1;
                    Queue.push(node);
                }
            }
        }
    }
    return -1;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

struct Node {
    int x, y;
    int Count;
    bool operator < (const Node &p) const{
       return p.Count < Count;
    }
};

int bfs(int a, int b);

int main()
{
//    freopen("in.txt", "r", stdin);
    while (cin>>M>>N && !(M==0&&N==0)) {
        memset(vis, false, sizeof(vis));
        int x, y;
        for (int i=0; i<M; ++i) {
            for (int j=0; j<N; ++j) {
                cin>>Map[i][j];
                if (Map[i][j] == 'Y') {
                    x = i;
                    y = j;
                }
            }
        }
        int least = bfs(x, y);
        cout<<least<<endl;
    }
    return 0;
}

int bfs(int a, int b)
{
    priority_queue<Node> Queue;
    Node node;
    node.x = a;
    node.y = b;
    node.Count = 0;
    Queue.push(node);
    vis[a][b] = 1;
    while (!Queue.empty()) {
        int nx = Queue.top().x;
        int ny = Queue.top().y;
        int nCount = Queue.top().Count;
        Queue.pop();
        if (Map[nx][ny] == 'T') {
            return nCount;
        }
        for (int i=0; i<4; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
                if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
                    if (Map[node.x][node.y] == 'B') {
                        node.Count = nCount + 2;
                    } else {
                        node.Count = nCount + 1;
                    }
                    vis[node.x][node.y] = 1;
                    Queue.push(node);
                }
            }
        }
    }
    return -1;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

struct Node {
    int x, y;
    int Count;
    friend bool operator < (const Node &a, const Node &b) {
       return b.Count < a.Count;
    }
};

int bfs(int a, int b);

int main()
{
//    freopen("in.txt", "r", stdin);
    while (cin>>M>>N && !(M==0&&N==0)) {
        memset(vis, false, sizeof(vis));
        int x, y;
        for (int i=0; i<M; ++i) {
            for (int j=0; j<N; ++j) {
                cin>>Map[i][j];
                if (Map[i][j] == 'Y') {
                    x = i;
                    y = j;
                }
            }
        }
        int least = bfs(x, y);
        cout<<least<<endl;
    }
    return 0;
}

int bfs(int a, int b)
{
    priority_queue<Node> Queue;
    Node node;
    node.x = a;
    node.y = b;
    node.Count = 0;
    Queue.push(node);
    vis[a][b] = 1;
    while (!Queue.empty()) {
        int nx = Queue.top().x;
        int ny = Queue.top().y;
        int nCount = Queue.top().Count;
        Queue.pop();
        if (Map[nx][ny] == 'T') {
            return nCount;
        }
        for (int i=0; i<4; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
                if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
                    if (Map[node.x][node.y] == 'B') {
                        node.Count = nCount + 2;
                    } else {
                        node.Count = nCount + 1;
                    }
                    vis[node.x][node.y] = 1;
                    Queue.push(node);
                }
            }
        }
    }
    return -1;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 300 + 5;
int M, N;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int dir[][4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

struct Node {
    int x, y;
    int Count;
};

bool operator < (const Node &a, const Node &b) {
   return b.Count < a.Count;
}

int bfs(int a, int b);

int main()
{
//    freopen("in.txt", "r", stdin);
    while (cin>>M>>N && !(M==0&&N==0)) {
        memset(vis, false, sizeof(vis));
        int x, y;
        for (int i=0; i<M; ++i) {
            for (int j=0; j<N; ++j) {
                cin>>Map[i][j];
                if (Map[i][j] == 'Y') {
                    x = i;
                    y = j;
                }
            }
        }
        int least = bfs(x, y);
        cout<<least<<endl;
    }
    return 0;
}

int bfs(int a, int b)
{
    priority_queue<Node> Queue;
    Node node;
    node.x = a;
    node.y = b;
    node.Count = 0;
    Queue.push(node);
    vis[a][b] = 1;
    while (!Queue.empty()) {
        int nx = Queue.top().x;
        int ny = Queue.top().y;
        int nCount = Queue.top().Count;
        Queue.pop();
        if (Map[nx][ny] == 'T') {
            return nCount;
        }
        for (int i=0; i<4; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            if (node.x>=0 && node.x<M && node.y>=0 && node.y<N) {
                if (!vis[node.x][node.y] && (Map[node.x][node.y] != 'R' && Map[node.x][node.y] != 'S')) {
                    if (Map[node.x][node.y] == 'B') {
                        node.Count = nCount + 2;
                    } else {
                        node.Count = nCount + 1;
                    }
                    vis[node.x][node.y] = 1;
                    Queue.push(node);
                }
            }
        }
    }
    return -1;
}

3、跳马问题

在中国象棋中,棋子活动的场所,叫做"棋盘",在长方形的平面上,绘有九条平行的竖线和十条平行横线相交组成,共九十个交叉点,棋子就摆在这些交叉点上。中间第五、第六两横线之间未画竖线的空白地带,称为"河界",整个棋盘就以"河界"分为相等的两部分;两方将帅坐镇、画有"米"字方格的地方,叫做"九宫"。

中国象棋中,马是威力很大的棋子。马走动的方法是一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称"马走斜"。马一次可走的选择点可以达到四周的八个点,故有"八面威风"之说。

我们约定最左下角点的坐标为(0,0),则最右上角的坐标为(9, 8)。上图中马在坐标(2, 2)处。它走一步可以到达坐标点(1, 0),(0, 1),(0, 3),(1, 4),(3, 4),(4, 3),(4, 1)或(3,0)。

我们约定当前棋盘上只有一个马,给出起点坐标和终点坐标,求从起点到终点,马最少要走几步?

Input

4个整数,前2个数表示起点坐标,后2个数表示终点坐标。

Output

一个整数,表示从起点到终点最少需要走的步数。

Sample Input

2 2 5 2

Sample Output

3

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

struct Node {
    int x, y;
    int steps;
};

const int maxn = 15;
bool vis[maxn][maxn];
int dir[][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}};
int x1, y1, x2, y2;

int bfs();

int main()
{
//    freopen("in.txt", "r", stdin);
    memset(vis, false, sizeof(vis));
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    x1 = 9-x1;
    x2 = 9-x2;
    printf("%d\n", bfs());
    return 0;
}

int bfs()
{
    Node node;
    node.x = x1;
    node.y = y1;
    node.steps = 0;
    vis[x1][y1] = true;
    queue<Node> Queue;
    Queue.push(node);
    while (!Queue.empty()) {
        int nx = Queue.front().x;
        int ny = Queue.front().y;
        int ns = Queue.front().steps;
        if (nx == x2 && ny == y2) {
            return ns;
        }
        Queue.pop();
        for (int i=0; i<8; ++i) {
            node.x = nx + dir[i][0];
            node.y = ny + dir[i][1];
            node.steps = ns + 1;
            if (0 <= node.x && node.x <= 9 && 0 <= node.y && node.y <= 8 && !vis[node.x][node.y]) {
                vis[node.x][node.y] = true;
                Queue.push(node);
            }
        }
    }
    return 0;
}

4、BJFU OJ 1548 大钉骑马走江湖

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

struct Node {
    int x, y;
    int step;
};

const int maxn = 100 + 5;
char Map[maxn][maxn];
bool vis[maxn][maxn];
int n, m;
int s_x, s_y, e_x, e_y;
int dir[][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}};
int flag[][2] = {{0, -1}, {-1, 0}, {-1, 0}, {0, 1}, {0, 1}, {1, 0}, {1, 0}, {0, -1}};

int bfs(void);

int main()
{
//    freopen("in.txt", "r", stdin);

    while (scanf("%d%d", &n, &m) != EOF) {
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                cin>>Map[i][j];
                if (Map[i][j] == 's') {
                    s_x = i;
                    s_y = j;
                } else if (Map[i][j] == 'e') {
                    e_x = i;
                    e_y = j;
                }
            }
        }
        printf("%d\n", bfs());
    }
    return 0;
}

int bfs(void)
{
    memset(vis, false, sizeof(vis));
    Node node;
    node.x = s_x;
    node.y = s_y;
    node.step = 0;
    vis[s_x][s_y] = true;
    queue<Node> Queue;
    Queue.push(node);
    while (!Queue.empty()) {
        int nx = Queue.front().x;
        int ny = Queue.front().y;
        int nstep = Queue.front().step;
        if (nx == e_x && ny == e_y) {
            return nstep;
        }
        Queue.pop();
        for (int i=0; i<8; ++i) {
            int a = nx + flag[i][0];
            int b = ny + flag[i][1];
            if (Map[a][b] == '.') {
                node.x = nx + dir[i][0];
                node.y = ny + dir[i][1];
                node.step = nstep + 1;
                if (node.x >= 0 && node.x <= n && node.y >=0 && node.y <= m && !vis[node.x][node.y] && Map[node.x][node.y] != '#') {
                    Queue.push(node);
                    vis[node.x][node.y] = true;
                }
            }
        }
    }
    return -1;
}

5、蓝桥杯2016省赛C语言B组7题 剪邮票

有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连)

比如,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。

注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

答案:

116

解题思路:

一:

选出5张不同邮票

规律:

(1)

某个邮票的上下左右可以分别用 -4 , +4 ,-1, +1 来表示

但要注意特殊情况,比如4、8、5、9

(2)

每个邮票至少和其它的一个邮票相连

假如将邮票a与邮票b相连的边与邮票b与邮票a相连的边看成是不同的

那么相连的边数应该 ≥ 8

#include <iostream>
#include <cstring>

using namespace std;

const int maxn = 12 + 5;
int num[maxn];
bool vis[maxn];
bool live[5];
int Count = 0;
int dir[4] = {-4, 4, -1 , 1};

bool check(void);

int main()
{
    for (int i=1; i<=8; ++i) {
        vis[i] = true;
        num[0] = i;
        for (int j=i+1; j<=9; ++j) {
            vis[j] = true;
            num[1] = j;
            for (int k=j+1; k<=10; ++k) {
                vis[k] = true;
                num[2] = k;
                for (int x=k+1; x<=11; ++x) {
                    vis[x] = true;
                    num[3] = x;
                    for (int y=x+1; y<=12; ++y) {
                        vis[y] = true;
                        num[4] = y;
                        memset(live, false, sizeof(live));
                        if (check()) {
                            ++Count;
                        }
                        vis[y] = false;
                    }
                    vis[x] = false;
                }
                vis[k] = false;
            }
            vis[j] = false;
        }
        vis[i] = false;
    }
    cout<<Count<<endl;
    return 0;
}

bool check(void)
{
    int edge = 0;
    for (int i=0; i<4; ++i) {
        for (int j=0; j<5; ++j) {
            if (!((num[j] == 4 || num[j] == 8) && i == 3) && !((num[j] == 5 || num[j] == 9) && i == 2)) {
                if (vis[num[j] + dir[i]] == 1) {
                    edge++;
                    live[j] = true;
                }
            }
        }
    }
    if (edge >= 8 && live[0] && live[1] && live[2] && live[3] && live[4]) {
        return true;
    }
    return false;
}
时间: 2024-12-05 14:40:02

bfs 2016.5.2的相关文章

聊一聊前端模板与渲染那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码): https://segmentfault.com/blog/frontenddriver 作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板.我们今天就来聊聊,拼装与渲染模板的那些事儿. 如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力 1 页面级的渲染 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串

使用 Raspberry Pi 上的传感器在 Node.js 中创建一个 IoT Bluemix 应用程序

先决条件 一个IBM Bluemix 帐号,一个 Raspberry Pi 2 或 3,一个 PIR 运动传感器 适用于本文的 Github 存储库 如果您是一位精明的 Bluemix 开发人员,您可能只想看看如何在 node.js 中与 IoT 建立连接,或者只想了解如何从此 github 存储库中拉取我的代码. git clone https://github.com/nicolefinnie/iot-nodejs-tutorial 以下是实现与 IBM IoT 平台连接在一起的 4 个 R

HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 997    Accepted Submission(s): 306 Problem Description The empire is under attack again. The general of empire is planning to defend his

[bfs,深度记录] East Central North America Regional Contest 2016 (ECNA 2016) D Lost in Translation

Problem D Lost in Translation The word is out that you’ve just finished writing a book entitled How to Ensure Victory at a Programming Contest and requests are flying in. Not surprisingly, many of these requests are from foreign countries, and while

HDU 5867 Sparse Graph (2016年大连网络赛 I bfs+补图)

题意:给你n个点m条边形成一个无向图,问你求出给定点在此图的补图上到每个点距离的最小值,每条边距离为1 补图:完全图减去原图 完全图:每两个点都相连的图 其实就是一个有技巧的bfs,我们可以看到虽然点很多但边很少,就使用vector存下每个点在原图中可以到达其他的哪些点,再使用bfs寻找此时起点可以到的其他点(每个距离都是1,所以越早到距离越短),接着更新起点继续查找:我们需要使用数组记录此时起点不能到的一些点(就是vector中原图起点可以到的点),但每次通过起点判断其他所有的点会超时,因此我

【2016 ICPC亚洲区域赛北京站 E】What a Ridiculous Election(BFS预处理)

Description In country Light Tower, a presidential election is going on. There are two candidates,  Mr. X1 and Mr. X2, and both of them are not like good persons. One is called a liar and the other is called a maniac. They tear(Chinese English word,

2016 ACM/ICPC 区域赛(北京) E 题 bfs

https://vjudge.net/problem/UVALive-7672 题意    输入一个五位数n 问由12345变到n的操作最少次数 不可达输出-1 有三种操作 1.交换相邻的位置 次数不限制 2.使某一位上的数字+1   最多使用三次 (mod 10) 3.使某一位上的数字*2   最多使用两次    (mod 10) 解析 很容易想到预处理,然后O(1) 查询,操作次数最少,所以就bfs,一层一层向外拓展. 需要注意的是 一个数被访问过还可以再被访问(进队列),因为得到一个数可以

POJ3967Ideal Path[反向bfs 层次图]

Ideal Path Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 1754   Accepted: 240 Description New labyrinth attraction is open in New Lostland amusement park. The labyrinth consists of n rooms connected by m passages. Each passage is colo

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共