BFS练习

 

UVA 439 Knight move

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard
exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy.

Of course you know that it is vice versa. So you offer him to write a program that solves the "difficult" part.

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

Input Specification

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a-h) representing the
column and a digit (1-8) representing the row on the chessboard.

Output Specification

For each test case, print one line saying "To get from xx to yy takes n knight moves.".

Sample Input

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

Sample Output

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.

国际象棋棋盘如下

国际象棋中马的行动规则

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int dir[][2] = {{-2,-1},{-2,1},{2,1},{2,-1},{1,2},{1,-2},{-1,-2},{-1,2}};//马的移动

int a[10][10],ex,ey;
char s1[5],s2[5];

struct node
{
    int x;
    int y;
    int step;
};
bool check(int x,int y)
{
    if(x < 0 || y < 0 || x >= 8 || y >= 8 || a[x][y])
        return true;
    return false;
}
int bfs()
{

    queue<node> Q;
    node p,next,q;
    p.x = s1[0] - 'a';
    p.y = s1[1] - '1';
    p.step = 0;
    ex = s2[0] - 'a';
    ey = s2[1] - '1';
    memset(a,0,sizeof(a));
    a[p.x][p.y] = 1;
    Q.push(p);
    while(!Q.empty())
    {
        q = Q.front();
        Q.pop();
        if(q.x == ex && q.y == ey)
            return q.step;
        for(int i = 0 ; i < 8; i++)
        {
            next.x = q.x + dir[i][0];
            next.y = q.y + dir[i][1];
            if(next.x == ex && next.y == ey)
                return q.step + 1;
            if(check(next.x,next.y))
                continue;
            next.step = q.step + 1;
            a[next.x][next.y] = 1;
            Q.push(next);
        }
    }
    return 0;
}
int main()
{
    while(scanf("%s %s",s1,s2)!=EOF)
    {
        printf("To get from %s to %s takes %d knight moves.\n",s1,s2,bfs());
    }
    return 0;
}

Catch That Cow   POJ 3278

Description

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input

Line 1: Two space-separated integers: N and K

Output

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint

The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#define MAXSIZE 100000 + 10
using namespace std;
int a[MAXSIZE] = {0};
struct node
{
    int x;
    int step;
};
int n,m;
int dfs()
{
    queue<node> Q;
    node q,p,next;
    q.x = n;
    q.step = 0;
    a[q.x] = 1;
    Q.push(q);
    while(!Q.empty())
    {
        p = Q.front();
        Q.pop();
        if(p.x == m)
            return p.step;
        for(int i = 0; i < 3; i++)
        {
            if(i == 0)
                next.x = p.x + 1;
            else if(i == 1)
                next.x = p.x - 1;
            else
                next.x = p.x * 2;
            if(next.x == m)
                return p.step + 1;
            if(next.x < 0 || next.x >= 100000 || a[next.x])
                continue;
            next.step = p.step + 1;
            a[next.x] = 1;
            Q.push(next);
        }
    }
}
int main()
{
    scanf("%d %d",&n,&m);
    printf("%d\n",dfs());
    return 0;
}

Find The Multiple  POJ - 1426 

Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains only the digits 0 and 1. You may assume that n is not greater than 200 and there is a corresponding m containing no more than 100 decimal digits.

Input

The input file may contain multiple test cases. Each line contains a value of n (1 <= n <= 200). A line containing a zero terminates the input.

Output

For each value of n in the input print a line containing the corresponding value of m. The decimal representation of m must not contain more than 100 digits. If there are multiple solutions for a given value of n, any one of them is acceptable.

Sample Input

2
6
19
0

Sample Output

10
100100100100100100
111111111111111111

注意数据大小 用long  long 

#include<cstdio>
#include<algorithm>
#include<queue>
#include<algorithm>
using namespace std;
int n;
queue<long long> Q;
void bfs()
{
    while(!Q.empty())
        Q.pop();
    long long m = 1;
    Q.push(m);
    while(!Q.empty())
    {
        m = Q.front();
        Q.pop();
        if(m % n == 0)
        {
            printf("%lld\n",m);
            return ;
        }
        Q.push(m * 10);
        Q.push(m * 10 + 1);
    }
}

int main()
{
    while(scanf("%d",&n)!=EOF && n)
    {
        bfs();
    }
    return 0;
}

非常可乐 HDU1495

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。

Input

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

Output

如果能平分的话请输出最少要倒的次数,否则输出"NO"。

Sample Input

7 4 3
4 1 3
0 0 0

Sample Output

NO
3

// 主要是倒水时的变化 有s - > m , s - > n, m - > s, m - >n ,n - > s, n - > m共六种倒水方法  知道有两个相等 且值为s/2

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

int n;
int m;
int s;

int v[105][105];

struct node
{
    int s;      //  s现在的数量
    int a;      //  表示大杯子中的数量
    int b;      //  表示小杯子中的数量
    int t;      //  步骤
};

int bfs()
{
    queue<node> Q;
    node now,to;
    memset(v,0,sizeof(v));
    now.s = s;
    now.a = 0;
    now.b = 0;
    now.t = 0;
    Q.push(now);
    v[now.a][now.b] = 1;

    while(!Q.empty())
    {
        now = Q.front();
        Q.pop();
        if((now.a == now.s && now.a == s/2) || (now.b == now.s && now.b == s/2) || (now.a == now.b && now.b == s/2))
            return now.t;
        if(now.s && now.a != n)     // s - > a  s不为空 a未满
        {
            int c = n - now.a;      // c表示当前a中剩余量
            if(now.s >= c)          //  s数量大于a的剩余量
            {
                to.a = n;           //  a被倒满
                to.s = now.s - c;
            }
            else                    //  s数量小于a的剩余量
            {
                to.a = now.a + now.s;   //  s全倒进去
                to.s = 0;
            }
            to.b = now.b;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
        if(now.s && now.b != m)     //  s - > b
        {
            int c = m - now.b;
            if(now.s >= c)
            {
                to.s = now.s - c;
                to.b = m;
            }
            else
            {
                to.s = 0;
                to.b = now.s + now.b;
            }
            to.a = now.a;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
        if(now.a && now.s != s)     //  a - > s
        {
            int c = s - now.s;
            if(now.a >= c)
            {
                to.s = s;
                to.a = now.a - c;
            }
            else
            {
                to.s = now.s + now.a;
                to.a = 0;
            }
            to.b = now.b;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
        if(now.a && now.b != m)        //  a - > b
        {
            int c = m - now.b;
            if(now.a >= c)
            {
                to.a = now.a - c;
                to.b = m;
            }
            else
            {
                to.a = 0;
                to.b = now.b + now.a;
            }
            to.s = now.s;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
        if(now.b && now.s != s)          // b - > s
        {
            int c = s - now.s;
            if(now.b >= c)
            {
                to.s = s;
                to.b = now.b - c;
            }
            else
            {
                to.s = now.b + now.s;
                to.b = 0;
            }
            to.a = now.a;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
        if(now.b && now.a != n)     //  b - > a
        {
            int c = n - now.a;
            if(now.b >= c)
            {
                to.a = n;
                to.b = now.b - c;
            }
            else
            {
                to.a = now.a + now.b;
                to.b = 0;
            }
            to.s = now.s;
            to.t = now.t + 1;
            if(!v[to.a][to.b])
            {
                Q.push(to);
                v[to.a][to.b] = 1;
            }
        }
    }
    return 0;
}
int main()
{
    while(scanf("%d %d %d",&s,&m,&n)!=EOF && s && m && n)
    {
        if(s%2)
            printf("NO\n");
        else
        {


        int ans = bfs();
        if(ans)
            printf("%d\n",ans);
        else
            printf("NO\n");
        }
    }

    return 0;
}

Dungeon Master  POJ - 2251 

You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides. 

Is an escape possible? If yes, how long will it take? 

Input

The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size). 
L is the number of levels making up the dungeon. 
R and C are the number of rows and columns making up the plan of each level. 
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.

Output

Each maze generates one line of output. If it is possible to reach the exit, print a line of the form 

Escaped in x minute(s).


where x is replaced by the shortest time it takes to escape. 
If it is not possible to escape, print the line 

Trapped!

Sample Input

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!

// 这个只是从二位变成三维  可以用三维数组v[][][]来看是否走过 和 八个方向 进行广搜索

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dir[][3] = {{0,0,1},{0,0,-1},{0,-1,0},{0,1,0},{1,0,0},{-1,0,0}};
int sx,sy,sz,ex,ey,ez;
char a[32][32][32];
int v[32][32][32];
int k,n,m;
struct node
{
    int x;
    int y;
    int z;
    int step;
};
int check(int x,int y,int z)
{
    if(x<0 || y<0 || z<0 || x>=k || y>=n || z>=m)
        return 1;
    else if(a[x][y][z] == '#')
        return 1;
    else if(v[x][y][z])
        return 1;
    return 0;
}
int bfs()
{
    node p,next,q;
    queue<node> Q;
    p.x = sx;
    p.y = sy;
    p.z = sz;
    p.step = 0;
    v[sx][sy][sz] = 1;
    Q.push(p);
    while(!Q.empty())
    {
        q = Q.front();
        Q.pop();
        if(q.x == ex && q.y == ey && q.z == ez)
            return q.step;
        for(int i = 0 ; i < 6; i ++)
        {
            next.x = q.x + dir[i][0];
            next.y = q.y + dir[i][1];
            next.z = q.z + dir[i][2];
            if(next.x == ex && next.y == ey && next.z ==ez)
                return q.step + 1;
            if(check(next.x,next.y,next.z))
                continue;
            v[next.x][next.y][next.z] = 1;
            next.step = q.step + 1;
            Q.push(next);
        }
    }
    return 0;
}
int main()
{
    while(scanf("%d %d %d",&k,&n,&m) && k && n && m)
    {
    for(int i = 0 ; i < k ; i++)
        for(int j = 0 ; j < n ; j ++)
            for(int c =0 ; c < m ; c++)
            {
                cin>>a[i][j][c];
                if(a[i][j][c] == 'S')
                {
                    sx = i;
                    sy = j;
                    sz = c;
                }
                if(a[i][j][c] == 'E')
                {
                    ex = i;
                    ey = j;
                    ez = c;
                }
            }
            memset(v,0,sizeof(v));
            int ans = bfs();
            if(ans)
                printf("Escaped in %d minute(s).\n",ans);
            else
                printf("Trapped!\n");

    }
    return 0;
}

 P1443 马的遍历 

题目描述

有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步

输入输出格式

输入格式:

一行四个数据,棋盘的大小和马的坐标

输出格式:

一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)

输入输出样例

输入样例#1: 

3 3 1 1

输出样例#1: 

0    3    2    
3    -1   1    
2    1    4    
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int dir[][2] = {{2,1},{-2,-1},{-1,-2},{1,2},{-1,2},{1,-2},{2,-1},{-2,1}};
struct node
{
    int x;
    int y;
};
int sx,sy,n,m,ex,ey;
int v[444][444];
int a[444][444];
bool check(int x,int y)
{
    if(x < 1 || y < 1 || x > n || y >m || v[x][y])
        return true;
    return false;
}
void bfs()
{

    queue<node> Q;
    node p,next;
    p.x = sx;
    p.y = sy;
    a[sx][sy] = 0;
    v[sx][sy] = 1;
    Q.push(p);
    while(!Q.empty())
    {
        p = Q.front();
        Q.pop();
        for(int i = 0 ; i < 8 ;i ++)
        {
            next.x = p.x + dir[i][0];
            next.y = p.y + dir[i][1];
            if(check(next.x,next.y))
                continue;
            v[next.x][next.y] = 1;
            a[next.x][next.y] = a[p.x][p.y] + 1;
            Q.push(next);
        }
    }
}
int main()
{
    memset(v,0,sizeof(v));
    memset(a,-1,sizeof(a));
    scanf("%d %d %d %d",&n,&m,&sx,&sy);
    bfs();
    for(int i =1; i <= n ;i ++)
        for(int j = 1; j <= m ; j++)
        {
            printf("%-5d",a[i][j]);
            if(j % m == 0)
                printf("\n");
        }
    return 0;
}

Prime Path   POJ - 3126 

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 
— It is a matter of security to change such things every now and then, to keep the enemy in the dark. 
— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 
— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 
— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 
— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 
— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime. 

Now, the minister of finance, who had been eavesdropping, intervened. 
— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 
— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 
— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 

1033 
1733 
3733 
3739 
3779 
8779 
8179

The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.

Input

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).

Output

One line for each case, either with a number stating the minimal cost or containing the word Impossible.

Sample Input

3
1033 8179
1373 8017
1033 1033

Sample Output

6
7
0
#include<stdio.h>
#include<queue>
#include<cmath>
#include<cstring>
#include<iostream>
#define MAXSIZE 10010
using namespace std;
int v[10010];
struct node
{
    int x;
    int step;
};
int s,e,t;
bool isprime(int x)
{
    for(int i = 2; i <= sqrt(x); i++)
        if(x % i == 0)
        return false;
    return true;
}
void bfs()
{
    queue<node> Q;
    node p,next;
    p.x = s;
    p.step = 0;
    v[s] = 1;
    Q.push(p);
    while(!Q.empty())
    {
        p = Q.front();
        Q.pop();
        if(p.x == e)
        {
            printf("%d\n",p.step);
            return ;
        }
        for(int i = 1; i <= 9 ; i += 2)     //  个位
        {
            int c = p.x / 10 * 10 + i;
            if(c != p.x && !v[c] && isprime(c))
            {
                next.x = c;
                v[c] = 1;
                next.step = p.step + 1;
                Q.push(next);
            }
        }
        for(int i = 0; i <= 9 ; i++)        // 十位
        {
            int c = p.x / 100 * 100 + i * 10 + p.x % 10;
            if(c != p.x && !v[c] && isprime(c))
            {
                next.x = c;
                v[c] = 1;
                next.step = p.step + 1;
                Q.push(next);
            }
        }
        for(int i = 0; i <= 9 ; i++)       // 百位
        {
            int c = p.x / 1000 * 1000 + i * 100 + p.x % 100;
            if(c != p.x && !v[c] && isprime(c))
            {
                next.x = c;
                v[c] = 1;
                next.step = p.step + 1;
                Q.push(next);
            }
        }
        for(int i = 1; i <= 9 ; i++)    //  千位
        {
            int c = i * 1000 + p.x % 1000;
            if(c != p.x && !v[c] && isprime(c))
            {
                next.x = c;
                v[c] = 1;
                next.step = p.step + 1;
                Q.push(next);
            }
        }
    }
    printf("Impossible\n");
    return ;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&s,&e);
        memset(v,0,sizeof(v));
        bfs();

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liuyang981122/article/details/81357867
BFS