[NWPU][2014][TRN][3]搜索 总结
2014-07-14 17:37
267 查看
这次总共就作出了五道题,后边的几道暂时还没什么思路。
A - 广搜 基础
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a pointN (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 orX
+ 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 andK
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
Sample Output
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.
这道题比较简单,让N通过加减1或自身乘2地方式最终得到K。直接广搜即可。直接AC了当时。
B - 广搜/深搜 基础
Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d
& %I64u
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)
The end of the input is indicated by a line consisting of two zeros.
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
Sample Output
从起点‘@’出发不能通过‘#’求出可以走到的‘.’的数量。第一次时,总是在第三个测试数据时无法通过,结果总是把所以的点都走了一遍,后来从写了一遍代码,就可以AC了,
可能是判断时出现了错误(实际我找了半天没找到)。
C - 广搜 基础
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
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 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
Sample Output
马踏棋盘的问题,找两个点的最少行进次数,本来这题应该是广搜的,结果我没注意标题,(其实我当时也分不清什么是深搜什么是广搜)直接套着B题的深搜也过了。⊙﹏⊙
D - 广搜 基础
Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d
& %I64u
Description
Background
Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him?
The Problem
Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance
to be faster than Somurolov.
For people not familiar with chess, the possible knight moves are shown in Figure 1.
Input
The input begins with the number n of scenarios on a single line by itself.
Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board
(4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers {0, ..., l-1}*{0, ..., l-1} specifying the starting and ending
position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess
board of that scenario.
Output
For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point.
If starting point and ending point are equal,distance is zero. The distance must be written on a single line.
Sample Input
Sample Output
这题我按照上一题的套路,直接跪了,才注意是广搜。这里又错了一次,忘了全局变量的队列,没有清空造成了错误。
E - 广搜记录路径 基础
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
SubmitStatus
Description
定义一个二维数组:
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
Sample Output
这个最大的问题是当时不知道怎么记录路径和怎么输出。
记录路径是用一个数组记录当前状态之前的状态,输出是用的是递归调用。搞明白这两个后这题就搞定了。
A - 广搜 基础
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a pointN (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 orX
+ 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 andK
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.
这道题比较简单,让N通过加减1或自身乘2地方式最终得到K。直接广搜即可。直接AC了当时。
#include <cstdio> #include <queue> using namespace std; const int MAXN = 100001; int N, K; int vis[MAXN]; int ret[MAXN]; queue<int> q; int BFS(int s, int d) { if (s == d) return 0; q.push(s); int cur; while (!q.empty()) { cur = q.front(); q.pop(); if (cur + 1 < MAXN && !vis[cur + 1]) { q.push(cur + 1); ret[cur + 1] = ret[cur] + 1; vis[cur + 1] = 1; } if (cur + 1 == d) break; if (cur - 1 >= 0 && !vis[cur - 1]) { q.push(cur - 1); ret[cur - 1] = ret[cur] + 1; vis[cur - 1] = 1; } if (cur - 1 == d) break; if (cur*2 < MAXN && !vis[cur *2]) { q.push(cur *2); ret[cur *2] = ret[cur] + 1; vis[cur *2] = 1; } if (cur *2 == d) break; } return ret[d]; } int main() { scanf("%d %d", &N,&K); printf("%d\n", BFS(N, K)); return 0; }
B - 广搜/深搜 基础
Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d
& %I64u
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)
The end of the input is indicated by a line consisting of two zeros.
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
从起点‘@’出发不能通过‘#’求出可以走到的‘.’的数量。第一次时,总是在第三个测试数据时无法通过,结果总是把所以的点都走了一遍,后来从写了一遍代码,就可以AC了,
可能是判断时出现了错误(实际我找了半天没找到)。
#include <stdio.h> #include <string.h> int n,m,cnt; char map[30][30]; int to[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; void dfs(int i,int j) { cnt++; map[i][j] = '#'; for(int k = 0; k<4; k++) { int x = i+to[k][0]; int y = j+to[k][1]; if(x<n && y<m && x>=0 && y>=0 && map[x][y] == '.') dfs(x,y); } return; } int main() { int i,j,fi,fj; while(~scanf("%d%d%",&m,&n)) { if(m == 0 && n == 0) break; for(i = 0; i<n; i++) { for(j = 0; j<m; j++) { scanf(" %c",&map[i][j]);//%c前边有个空格,要不把回车读进去了 if(map[i][j] == '@') { fi = i; fj = j; } } } cnt = 0; dfs(fi,fj); printf("%d\n",cnt); } return 0; }
C - 广搜 基础
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
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 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.
马踏棋盘的问题,找两个点的最少行进次数,本来这题应该是广搜的,结果我没注意标题,(其实我当时也分不清什么是深搜什么是广搜)直接套着B题的深搜也过了。⊙﹏⊙
#include <cstdio> #include <string> #include <cstring> using namespace std; const int dir[8][2]= {1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,1,-2,-1}; const int N = 10; char ch1, ch2, ch3, ch4; int x1, y1, x2, y2; int used ; void DFS(int x, int y, int t) { if(x>7||x<0||y>7||y<0||used[x][y]<=t) return; used[x][y]=t; for (int i = 0; i < 8; i++) { int tx=x+dir[i][0]; int ty=y+dir[i][1]; DFS(tx,ty,t+1); } } int main() { while (scanf("%c%c %c%c", &ch1, &ch2, &ch3, &ch4) != EOF) { getchar(); x1 = ch1 - 'a', y1 = ch2 - '1'; x2 = ch3 - 'a', y2 = ch4 - '1'; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) used[i][j] = 64; DFS(x1, y1, 0); printf("To get from %c%c to %c%c takes %d knight moves.\n", ch1, ch2, ch3, ch4, used[x2][y2]); } }
D - 广搜 基础
Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d
& %I64u
Description
Background
Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him?
The Problem
Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance
to be faster than Somurolov.
For people not familiar with chess, the possible knight moves are shown in Figure 1.
Input
The input begins with the number n of scenarios on a single line by itself.
Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board
(4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers {0, ..., l-1}*{0, ..., l-1} specifying the starting and ending
position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess
board of that scenario.
Output
For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point.
If starting point and ending point are equal,distance is zero. The distance must be written on a single line.
Sample Input
3 8 0 0 7 0 100 0 0 30 50 10 1 1 1 1
Sample Output
5 28 0
这题我按照上一题的套路,直接跪了,才注意是广搜。这里又错了一次,忘了全局变量的队列,没有清空造成了错误。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<queue> using namespace std; const int MAXN = 600; struct point { int x; int y; int dis; }; int vis[MAXN][MAXN]; int X[8]={-2,-2,-1,-1,2,2,1,1}; int Y[8]={-1,1,-2,2,-1,1,-2,2}; int bfs(); int cango(int i,int j); int n; queue<point>myqueue; point start,end; int main() { int t; scanf("%d",&t); while (t--) { scanf("%d",&n); memset(vis,0,sizeof(vis)); scanf("%d%d",&start.x,&start.y); scanf("%d%d",&end.x,&end.y); if(start.x == end.x && start.y == end.y) { printf("0\n"); continue; } while(!myqueue.empty()) //清空队列,因为队列是全局的,要不就跪了 myqueue.pop(); printf("%d\n",bfs()); } return 0; } int bfs() { start.dis = 0; myqueue.push(start); vis[start.x][start.y] = 1; point temp,next; while (!myqueue.empty()) { temp = myqueue.front(); myqueue.pop(); int k; for(k=0;k<8;k++) { next.x = temp.x+X[k]; next.y = temp.y+Y[k]; if(cango(next.x,next.y)) { next.dis = temp.dis + 1; if(next.x == end.x && next.y == end.y) return next.dis; myqueue.push(next); vis[next.x][next.y] = 1; } } } } int cango(int i,int j) { if(i>=0&&i<n&&j>=0&&j<n&&vis[i][j]==0) return 1; return 0; }
E - 广搜记录路径 基础
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
SubmitStatus
Description
定义一个二维数组:
int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, };
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0
Sample Output
(0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (3, 4) (4, 4)
这个最大的问题是当时不知道怎么记录路径和怎么输出。
记录路径是用一个数组记录当前状态之前的状态,输出是用的是递归调用。搞明白这两个后这题就搞定了。
#include<stdio.h> #include<string.h> #include<stdlib.h> int map[5][5]; int visit[5][5]; int pre[100]; //记录每一个状态的前一个状态 struct cam { int x; int y; }list[100]; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int go(int x,int y) { if(0<=x&&x<5&&0<=y&&y<5&&map[x][y]==0) return 1; return 0; } void print(int x) { int t; t=pre[x]; if(t==0) { printf("(0, 0)\n"); printf("(%d, %d)\n",list[x].x,list[x].y); return; } else print(t); printf("(%d, %d)\n",list[x].x,list[x].y); } void bfs() { int i,head,tail; int x,y,xx,yy; memset(visit,0,sizeof(visit)); head=0; tail=1; list[0].x=0; list[0].y=0; pre[0]=-1; while(head<tail) { x=list[head].x; y=list[head].y; if(x==4&&y==4) { print(head); return; } for(i=0;i<4;i++) { xx=x+dir[i][0]; yy=y+dir[i][1]; if(!visit[xx][yy]&&go(xx,yy)) { visit[xx][yy]=1; list[tail].x=xx; list[tail].y=yy; pre[tail]=head; tail++; } } head++; } return; } int main() { int i,j; for(i=0;i<5;i++) for(j=0;j<5;j++) scanf("%d",&map[i][j]); bfs(); return 0; }
相关文章推荐
- 7.12 [NWPU][2014][TRN][3]搜索 POJ 1562 H - 深搜/广搜 基础
- 7.12 [NWPU][2014][TRN][4]搜索 C - 广搜 基础
- 7-12 [NWPU][2014][TRN][3]搜索 D - 广搜 基础 POJ 1915
- [NWPU][2014][TRN][5]二分和贪心 HDU 4296
- [NWPU][2014][TRN][16]图论拓扑排序 E - 基础 HDU 1285
- [NWPU][2014][TRN][12]并查集D - A Bug's Life POJ 2492
- [NWPU][2014][TRN][17]最小生成树 B - 基础 POJ 2421
- [NWPU][2014][TRN][16]图论拓扑排序 H - 基础
- [NWPU][2014][TRN][22]RMQ和LCA E - LCA POJ 1470
- [NWPU][2014][TRN][5]二分和贪心 M - 贪心 基础 POJ 2709
- [NWPU][2014][TRN][21]数论入门 B - 扩展欧几里得 POJ 1061
- [NWPU][2014][TRN][13]线段树第一讲 B - 基础 POJ 3264
- [NWPU][2014][TRN][22]RMQ和LCA C - RMQ POJ 3264
- [NWPU][2014][TRN][13]线段树第一讲 A - 基础 POJ 2352
- [NWPU][2014][TRN][18]最短路问题 A - 模板 POJ 2387
- Lucene学习总结之七:Lucene搜索过程解析(3)
- lucene常用搜索总结
- Lucene学习总结之七:Lucene搜索过程解析
- 总结:谷歌按时间搜索
- Google搜索总结