搜索专题训练【CSUST_Newer_12级入门】

                                                 搜索专题(Newer)



题解:

A bfs依次遍历周围的八个方向(马走日)

B bfs注意记录当前方向和转弯数

C bfs入门题目,注意要清空队列

D dfs入门,周围加边四个方向深搜即可。

E dfs.八连块问题 只要周围的八个方向的图是一样的,则都算是同一个八连块,记录共有多少个八连块即可。

D dfs 深度遍历每一条路即可,只是要边遍历边记录路径,最后输出路径就好了

E dfs+奇偶剪枝优化



    ID Title
13 / 19 Problem A Knight Moves
6 / 38 Problem B 逃离迷宫
8 / 40 Problem C Catch That Cow
8 / 8 Problem D Red and Black
6 / 9 Problem E Oil Deposits
4 / 6 Problem F 哈密顿绕行世界问题
4 / 19 Problem G Tempter of the Bone


A hdu 1372

Knight Moves

 

Problem Description
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
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
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.
 

Source
University of Ulm Local Contest 1996
 

Recommend
Eddy


/*
算法:bfs
思路:八个方向依次遍历即可
注意:队列元素Node 不仅包含了点的位置还包含了走到当前所用的步数
      注意骑士周游问题:马走日八个方向
A	
Accepted	
248 KB	
15 ms	
C++
*/
#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;

bool vis[30][30]; //标记是否走过
int dir[8][2] = { 1,2, 2,1, 2,-1, 1,-2, -1,-2, -2,-1, -2,1, -1,2 }; //马走日 八个方向
int sx, sy, ex, ey; //记录起点和终点
char s_x, e_x;

struct Node
{
    int x, y;
    int step;
};
queue<Node> q;

bool inMap(int x, int y) //判断是否在棋盘内
{
    if(x < 1 || x > 8 || y < 1 || y > 8) return false;
    return true;
}

void bfs(int x, int y) //广度优先遍历
{
    while(!q.empty()) q.pop(); //清空队列

    Node start;
    start.x = x; start.y = y; start.step = 0; //起点
    vis[x][y] = true; //标记起点已走
    q.push(start); //起点入队

    while(!q.empty()) //当队列非空
    {
        Node now = q.front(); //取队首
        q.pop(); //弹出队首
        if(now.x == ex && now.y == ey) //到达终点
        {
            printf("To get from %c%d to %c%d takes %d knight moves.\n", s_x, sy, e_x, ey, now.step);
            return;
        }

        Node next;
        for(int i = 0; i < 8; i++) //依次遍历每个点的八个方向
        {
            next.x = now.x+dir[i][0];
            next.y = now.y+dir[i][1];

            if(!inMap(next.x, next.y)) continue; //不在图中,则跳过此点

            if(!vis[next.x][next.y]) //没有被遍历过
            {
                vis[next.x][next.y] = true; //记录已被遍历
                next.step = now.step+1; //确定条到这一步,步数+1
                q.push(next); //入队
                if(next.x == ex && next.y == ey) //如果到达终点
                {
                    printf("To get from %c%d to %c%d takes %d knight moves.\n", s_x, sy, e_x, ey, next.step);
                    return;
                }
            }
        }
    }
}
int main()
{//freopen("in.txt", "r", stdin);
    while(scanf("%c%d%*c%c%d%*c", &s_x, &sy, &e_x, &ey) != EOF)
    {//注意输入时的*c 运行bfs前可以自己测试一下 ,最好还是用cin输入了
        memset(vis, false, sizeof(vis)); //初始化遍历数组

        sx = s_x-'a'+1; //字符数字化
        ex = e_x-'a'+1;

        bfs(sx, sy);
    }
    return 0;
}



B_hdu 1728


逃离迷宫

 

Problem Description
  给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
 

Input
  第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,
  第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x 1, y 1, x 2, y 2 (1 ≤ k ≤ 10, 1 ≤ x 1, x 2 ≤ n, 1 ≤ y 1, y 2 ≤ m),其中k表示gloria最多能转的弯数,(x 1, y 1), (x 2, y 2)表示两个位置,其中x 1,x 2对应列,y 1, y 2对应行。
 

Output
  每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。
 

Sample Input
   
   
   
   
2 5 5 ...** *.**. ..... ..... *.... 1 1 1 1 3 5 5 ...** *.**. ..... ..... *.... 2 1 1 1 3
 

Sample Output
   
   
   
   
no yes
 

Source
“网新恩普杯”杭州电子科技大学程序设计邀请赛
 

Recommend
lcy
/*
算法:暴力 bfs
思路:还是像以前一样定义一个结构体入队。
      但是结构体中除了原来定义过的 x,y坐标
      还新加了turn(走到当前点,转的弯),dir(当前方向)。
注意:放向的转换,纠结了好久,最后看了篇题解,每个点都记录了方向就解决了。
      输入:确定起点和终点时是先输入列再输入行。
      输出:小写输出,开始没注意一直WA到死啊。
B
Accepted
412 KB
62 ms
C++
830 B
*/
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;

const int maxn = 105;
const int Max = 1<<30; //作为初始化值
char map[maxn][maxn];
int turn[maxn][maxn]; //记录走到当前坐标转的弯
int dir[4][2] = { 0,1, 1,0, 0,-1, -1,0}; //上下左右四个方向都可以走
int k, sx, sy, ex, ey;
int m, n;

struct Node
{
    int x, y; //点的位置
    int turn ,dir; //转的弯和当前方向
};
queue<Node> q; //结构体队列

bool inMap(int x, int y) //判断是否在图中
{
    if(x < 1 || x > m || y < 1 || y > n) return false;
    return true;
}

void bfs(int x, int y)
{
    while(!q.empty()) q.pop(); //清空队列
    Node start;
    start.x = x; start.y = y; start.turn = 0; start.dir = -1; //起点
    turn[x][y] = 0; //起点可以任意转弯
    q.push(start);  //入队

    while(!q.empty()) //当队列非空
    {
        Node now = q.front(); // 取队首
        q.pop(); //弹出队首

        Node next;
        for(int i = 0; i < 4; i++) //依次遍历周围的四个方向
        {
            next = now;
            next.x += dir[i][0];
            next.y += dir[i][1];

            //如果不在图中,或者不可以走,则跳过此点
            if(!inMap(next.x, next.y) || map[next.x][next.y] == '*') continue;

            //如果当前点now不是起点,而且转入的方向与原方向不同,则当前点转弯数+1
            if(next.dir != -1 && next.dir != i) next.turn++;

            //如果走到当前点转的弯超过了限定的转弯数,则跳过此点
            if(next.turn > k) continue;

            //如果当前点符合要求,输出yes结束程序
            if(next.turn <= k && next.x == ex && next.y == ey)
            {
                printf("yes\n");
                return;
            }

            //否则当前点入队
            if(turn[next.x][next.y] >= next.turn)
            {
                turn[next.x][next.y] = next.turn;
                next.dir = i;
                q.push(next);
            }
        }
    }
    printf("no\n"); //遍历完所有均不能满足条件
    return;

}
int main()
{//freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T); //T组测试数据
    while(T--)
    {
        scanf("%d%d", &m, &n); //m行n列
        for(int i = 1; i <= m; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                cin>>map[i][j];
                turn[i][j] = Max; //初始化转弯数为最大值
            }
        }
        cin>>k>>sy>>sx>>ey>>ex; //注意输入的顺序

        if(sx == ex && sy == ey) printf("yes\n"); //如果相等,则直接输出注意小写输出
        else bfs(sx, sy);
    }
    return 0;
}



C_hdu 2717


POJ_3278

Catch That Cow

 

Problem 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 X - 1 or X + 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.
 

Source
USACO 2007 Open Silver
 

Recommend
teddy

下面的代码已经很清楚了,如果还是不了解,请看我的分析博客:点击打开链接
 
 
//Accepted	984K	79MS	C++	1128B	2012-11-10 00:44:26
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;

const int maxn=100001;

bool vis[maxn];//标记数组
int step[maxn];//记录到了每一位置所走的步数
queue <int> q;//定义队列

int bfs(int n,int k)
{
    int head,next;
    q.push(n);   //开始FJ在n位置,n入队
    step[n]=0;
    vis[n]=true; //标记已访问
    while(!q.empty())  //当队列非空
    {
        head=q.front();  //取队首
        q.pop();         //弹出对首
        for(int i=0;i<3;i++)     //FJ的三种走法
        {
            if(i==0) next=head-1;
            else if(i==1) next=head+1;
            else next=head*2;
            if(next<0 || next>=maxn) continue; //排除出界情况
            if(!vis[next])  //如果next位置未被访问
            {
                q.push(next);    //入队
                step[next]=step[head]+1;  //步数+1
                vis[next]=true;  //标记已访问
            }
            if(next==k) return step[next];  //当遍历到结果,返回步数
        }
    }
}
int main()
{
    int n,k;
    while(cin>>n>>k)
    {
        memset(step,0,sizeof(step));
        memset(vis,false,sizeof(vis));
        
        while(!q.empty()) q.pop(); //注意调用前要先清空
        if(n>=k) printf("%d\n",n-k);
        else printf("%d\n",bfs(n,k));
    }
    return 0;
}
 
 
 
 



D_hdu 1312


POJ 1979


Red and Black

 
Problem Description
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can't move on red tiles, he can move only on black tiles.

Write a program to count the number of black tiles which he can reach by repeating the moves described above. 
 

Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.

There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.

'.' - a black tile 
'#' - a red tile 
'@' - a man on a black tile(appears exactly once in a data set) 
 

Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself). 
 

Sample Input
   
   
   
   
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 11 9 .#......... .#.#######. .#.#.....#. .#.#.###.#. .#.#..@#.#. .#.#####.#. .#.......#. .#########. ........... 11 6 ..#..#..#.. ..#..#..#.. ..#..#..### ..#..#..#@. ..#..#..#.. ..#..#..#.. 7 7 ..#.#.. ..#.#.. ###.### ...@... ###.### ..#.#.. ..#.#.. 0 0
 

Sample Output
   
   
   
   
45 59 6 13
 

Source
Asia 2004, Ehime (Japan), Japan Domestic
 

Recommend
Eddy
/*
题意:'#'不可走,'.'可走,'@'为起点。
      求从'@'开始走,一共可以走完多少个'.','@'也算一个。
思路:dfs深度遍历周围的四个方向
优化:遍历前,图的四周加边。
注意:先输入高度,再输入宽。也就是先输入行数再输入列数。
D
Accepted
268 KB
15 ms
C++
876 B
*/
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

char map[25][25];
int w, h;
int sx, sy; //起点
int ans;

void dfs(int x, int y) //深度遍历
{
    if(map[x][y] == '#') return; //不可走,马上跳出
    ans++;   //可以走 结果+1
    map[x][y] = '#'; // 标记已走
    dfs(x-1, y); dfs(x+1, y); //遍历周围的四个方向
    dfs(x, y-1); dfs(x, y+1);
}
int main()
{
    while(scanf("%d%d", &w, &h) != EOF) //先输入列数 再输入行数
    {
        if(w == 0) break; // 输入0即结束
        for(int i = 1; i <= h; i++)
        {
            for(int j = 1; j <= w; j++)
            {
                cin>>map[i][j];
                if(map[i][j] == '@') //起点
                {
                    sx = i;
                    sy = j;
                }
            }
        }

        for(int i = 0; i <= h+1; i++) map[i][0] = map[i][w+1] = '#'; //第0列和第w+1列加边 不可走
        for(int i = 0; i <= w+1; i++) map[0][i] = map[h+1][i] = '#'; //第0行和第h+1行加边 不可走
        ans = 0; //初始化结果
        dfs(sx, sy);
        printf("%d\n", ans);
    }
    return 0;
}


E

hdu 1241


POJ 1562

Oil Deposits

 
Problem Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid. 
 

Input
The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
 

Output
For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
 

Sample Input
   
   
   
   
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
 

Sample Output
   
   
   
   
0 1 2 2
 

Source
Mid-Central USA 1997
 

Recommend
Eddy
 

F

hdu 2181


哈密顿绕行世界问题

 


Problem Description
一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。 
 

Input
前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出.
 

Output
输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output
 

Sample Input
   
   
   
   
2 5 20 1 3 12 2 4 10 3 5 8 1 4 6 5 7 19 6 8 17 4 7 9 8 10 16 3 9 11 10 12 15 2 11 13 12 14 20 13 15 18 11 14 16 9 15 17 7 16 18 14 17 19 6 18 20 1 13 19 5 0
 

Sample Output
   
   
   
   
1: 5 1 2 3 4 8 7 17 18 14 15 16 9 10 11 12 13 20 19 6 5 2: 5 1 2 3 4 8 9 10 11 12 13 20 19 18 14 15 16 17 7 6 5 3: 5 1 2 3 10 9 16 17 18 14 15 11 12 13 20 19 6 7 8 4 5 4: 5 1 2 3 10 11 12 13 20 19 6 7 17 18 14 15 16 9 8 4 5 5: 5 1 2 12 11 10 3 4 8 9 16 15 14 13 20 19 18 17 7 6 5 6: 5 1 2 12 11 15 14 13 20 19 18 17 16 9 10 3 4 8 7 6 5 7: 5 1 2 12 11 15 16 9 10 3 4 8 7 17 18 14 13 20 19 6 5 8: 5 1 2 12 11 15 16 17 18 14 13 20 19 6 7 8 9 10 3 4 5 9: 5 1 2 12 13 20 19 6 7 8 9 16 17 18 14 15 11 10 3 4 5 10: 5 1 2 12 13 20 19 18 14 15 11 10 3 4 8 9 16 17 7 6 5 11: 5 1 20 13 12 2 3 4 8 7 17 16 9 10 11 15 14 18 19 6 5 12: 5 1 20 13 12 2 3 10 11 15 14 18 19 6 7 17 16 9 8 4 5 13: 5 1 20 13 14 15 11 12 2 3 10 9 16 17 18 19 6 7 8 4 5 14: 5 1 20 13 14 15 16 9 10 11 12 2 3 4 8 7 17 18 19 6 5 15: 5 1 20 13 14 15 16 17 18 19 6 7 8 9 10 11 12 2 3 4 5 16: 5 1 20 13 14 18 19 6 7 17 16 15 11 12 2 3 10 9 8 4 5 17: 5 1 20 19 6 7 8 9 10 11 15 16 17 18 14 13 12 2 3 4 5 18: 5 1 20 19 6 7 17 18 14 13 12 2 3 10 11 15 16 9 8 4 5 19: 5 1 20 19 18 14 13 12 2 3 4 8 9 10 11 15 16 17 7 6 5 20: 5 1 20 19 18 17 16 9 10 11 15 14 13 12 2 3 4 8 7 6 5 21: 5 4 3 2 1 20 13 12 11 10 9 8 7 17 16 15 14 18 19 6 5 22: 5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 23: 5 4 3 2 12 11 10 9 8 7 6 19 18 17 16 15 14 13 20 1 5 24: 5 4 3 2 12 13 14 18 17 16 15 11 10 9 8 7 6 19 20 1 5 25: 5 4 3 10 9 8 7 6 19 20 13 14 18 17 16 15 11 12 2 1 5 26: 5 4 3 10 9 8 7 17 16 15 11 12 2 1 20 13 14 18 19 6 5 27: 5 4 3 10 11 12 2 1 20 13 14 15 16 9 8 7 17 18 19 6 5 28: 5 4 3 10 11 15 14 13 12 2 1 20 19 18 17 16 9 8 7 6 5 29: 5 4 3 10 11 15 14 18 17 16 9 8 7 6 19 20 13 12 2 1 5 30: 5 4 3 10 11 15 16 9 8 7 17 18 14 13 12 2 1 20 19 6 5 31: 5 4 8 7 6 19 18 17 16 9 10 3 2 12 11 15 14 13 20 1 5 32: 5 4 8 7 6 19 20 13 12 11 15 14 18 17 16 9 10 3 2 1 5 33: 5 4 8 7 17 16 9 10 3 2 1 20 13 12 11 15 14 18 19 6 5 34: 5 4 8 7 17 18 14 13 12 11 15 16 9 10 3 2 1 20 19 6 5 35: 5 4 8 9 10 3 2 1 20 19 18 14 13 12 11 15 16 17 7 6 5 36: 5 4 8 9 10 3 2 12 11 15 16 17 7 6 19 18 14 13 20 1 5 37: 5 4 8 9 16 15 11 10 3 2 12 13 14 18 17 7 6 19 20 1 5 38: 5 4 8 9 16 15 14 13 12 11 10 3 2 1 20 19 18 17 7 6 5 39: 5 4 8 9 16 15 14 18 17 7 6 19 20 13 12 11 10 3 2 1 5 40: 5 4 8 9 16 17 7 6 19 18 14 15 11 10 3 2 12 13 20 1 5 41: 5 6 7 8 4 3 2 12 13 14 15 11 10 9 16 17 18 19 20 1 5 42: 5 6 7 8 4 3 10 9 16 17 18 19 20 13 14 15 11 12 2 1 5 43: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 44: 5 6 7 8 9 16 17 18 19 20 1 2 12 13 14 15 11 10 3 4 5 45: 5 6 7 17 16 9 8 4 3 10 11 15 14 18 19 20 13 12 2 1 5 46: 5 6 7 17 16 15 11 10 9 8 4 3 2 12 13 14 18 19 20 1 5 47: 5 6 7 17 16 15 11 12 13 14 18 19 20 1 2 3 10 9 8 4 5 48: 5 6 7 17 16 15 14 18 19 20 13 12 11 10 9 8 4 3 2 1 5 49: 5 6 7 17 18 19 20 1 2 3 10 11 12 13 14 15 16 9 8 4 5 50: 5 6 7 17 18 19 20 13 14 15 16 9 8 4 3 10 11 12 2 1 5 51: 5 6 19 18 14 13 20 1 2 12 11 15 16 17 7 8 9 10 3 4 5 52: 5 6 19 18 14 15 11 10 9 16 17 7 8 4 3 2 12 13 20 1 5 53: 5 6 19 18 14 15 11 12 13 20 1 2 3 10 9 16 17 7 8 4 5 54: 5 6 19 18 14 15 16 17 7 8 9 10 11 12 13 20 1 2 3 4 5 55: 5 6 19 18 17 7 8 4 3 2 12 11 10 9 16 15 14 13 20 1 5 56: 5 6 19 18 17 7 8 9 16 15 14 13 20 1 2 12 11 10 3 4 5 57: 5 6 19 20 1 2 3 10 9 16 15 11 12 13 14 18 17 7 8 4 5 58: 5 6 19 20 1 2 12 13 14 18 17 7 8 9 16 15 11 10 3 4 5 59: 5 6 19 20 13 12 11 10 9 16 15 14 18 17 7 8 4 3 2 1 5 60: 5 6 19 20 13 14 18 17 7 8 4 3 10 9 16 15 11 12 2 1 5
 

Author
Zhousc
 

Source
ECJTU 2008 Summer Contest
 

Recommend
lcy

注意:排序。

/*
*F	
*Accepted	
*204 KB	
*0 ms	
*G++	
*867 B	
*2013-03-26 
*/ 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int path[22];
int point[21][3];
bool vis[21];

int m;
int Case;

void dfs(int a, int n)
{
	vis[a] = true;
	path[n] = a;
	if(n == 21 && path[n] == m) //回到起点 
	{
		printf("%d: ",++Case);
		for(int i = 1; i <= 21; i++) printf(" %d", path[i]);
		printf("\n");
		return;
	}
	else if(n >= 21) return;
	for(int i = 0; i < 3; i++)
	{
		int x = point[a][i];
		if((x != m && !vis[x]) || (x == m && n == 20)) //如果没有走过,或者下一个点回到起点 
		{ //注意:前一个条件如果没有写 x != m 则会影响后面的结果 也就是 m 会在路径中重复出现 
			dfs(x, n+1);
			vis[x] = false;
		} 
	} 
}
int main()
{
	for(int i = 1; i <= 20; i++)
	{
		scanf("%d%d%d", &point[i][0], &point[i][1], &point[i][2]);
		sort(point[i], point[i]+3);
	}
	 
	while(scanf("%d", &m) != EOF)
	{
		Case = 0;
		if(m == 0) break;
		
		memset(vis, false, sizeof(vis));
		
		dfs(m, 1);
	}
	return 0;
}




G_hdu 1010

Tempter of the Bone

 

Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
 

Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter; 
'S': the start point of the doggie; 
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.
 

Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
 

Sample Input
   
   
   
   
4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
 

Sample Output
   
   
   
   
NO YES
 

Author
ZHANG, Zheng
 

Source
ZJCPC2004
 

Recommend
JGShining

你可能感兴趣的:(搜索专题训练【CSUST_Newer_12级入门】)