搜索入门题

http://poj.org/problem?id=2488

A Knight's Journey
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 32979Accepted: 11244

Description

搜索入门题 - 风未定 - NGUNAUJ Background 
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey 
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans? 

Problem 
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.

Input

The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . .

Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number. 
If no such path exist, you should output impossible on a single line.

Sample Input

3
1 1
2 3
4 3

Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

Source

TUD Programming Contest 2005, Darmstadt, Germany
提交了几次都是 wa最后找到了问题所在,搜索的方向性,,改变dir数组就行了。因为题中要求的是按字母顺序输出路径。。http://poj.org/problem?id=2488
总之,自己的英文还有待提高,,poj英文题太。。哎~都说这道题是水题。我用了一个下午才作对。而且还百度了几手。。惭愧~

#include<iostream>
#include<cstdio>
using namespace std;
int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};
int path[26][2];
int m,n;
int vis[26][26];
bool flag;
void dfs(int i,int j,int k)
{
if(k==m*n)
{ for(int i=0;i<k;i++)
cout<<char(path[i][0]+'A')<<path[i][1]+1;
cout<<endl;
flag=1;
}
else for(int x=0;x<8;x++)
{
int p=i+dir[x][0];
int q=j+dir[x][1];
if(p>=0&&p<n&&q>=0&&q<m&&!vis[p][q]&&!flag)
{
vis[p][q]=1;
path[k][0]=p;
path[k][1]=q;
dfs(p,q,k+1);
vis[p][q]=0;
}
}
}
int main()
{
int t;
cin>>t;
for(int i=0;i<t;i++)
{ memset(vis,0,sizeof(vis));
cin>>m>>n;
flag=false;
printf("Scenario #%d:\n",i+1);
vis[0][0]=1;
path[0][0]=0;path[0][1]=0;//x,y
dfs(0,0,1);
if(!flag)cout<<"impossible"<<endl;
cout<<endl;
}
return 0;
}


(2) http://poj.org/problem?id=3278
Catch That Cow
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 51898Accepted: 16292

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.

Source

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#include <stack>
#define maxn 100000+8
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
#define INF 1<<30
const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;
struct node
{
int dist;
int val;
};
int n,k;
int vis[maxn];
bool cmp(int a,int b)
{
return a>b;
}
queue<node>q;
int bfs()
{
while(!q.empty())q.pop();
cle(vis);
node u;
u.val=n,u.dist=0;
q.push(u);
while(!q.empty())
{
u=q.front(),q.pop();
if(u.val==k)return u.dist;
node v;
v.val=u.val*2;
if(v.val<=maxn&&v.val>=0&&!vis[v.val])
{
vis[v.val]=1;
v.dist=u.dist+1;
q.push(v);
}
v.val=u.val+1;
if(v.val<=maxn&&v.val>=0&&!vis[v.val])
{
vis[v.val]=1;
v.dist=u.dist+1;
q.push(v);
}
v.val=u.val-1;
if(v.val<=maxn&&v.val>=0&&!vis[v.val])
{
vis[v.val]=1;
v.dist=u.dist+1;
q.push(v);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&k)!=EOF)
{
printf("%d\n",bfs());
}
return 0;
}

//建树的过程
Dungeon Master
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 18145Accepted: 7048

Description

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!

Source

#include<iostream>
#include<queue>
using namespace std;
char map[35][35][35];
#define mem(a) memset(a,0,sizeof(a))
#define judge(x,y,z) !vis[x][y][z]&&map[x][y][z]!='#'&&x>=0&&x<l&&y>=0&&y<m&&z>=0&&z<n
int vis[35][35][35];
int dir[6][3]={{1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1}};
int l,m,n;
struct node
{
int x,y,z;
int dist;
};
int bfs(int x,int y,int z)
{
queue<node>q;
mem(vis);
node u;
u.x=x;u.y=y;u.z=z;u.dist=0;
q.push(u);
while(!q.empty())
{
u=q.front();
q.pop();
if(map[u.x][u.y][u.z]=='E')return u.dist;
for(int i=0;i<6;i++)
{
node v;
v.x=u.x+dir[i][0];
v.y=u.y+dir[i][1];
v.z=u.z+dir[i][2];
if(judge(v.x,v.y,v.z))
{
vis[v.x][v.y][v.z]=1;
v.dist=u.dist+1;
q.push(v);
}
}
}
return 0;
}
int main()
{
int sx,sy,sz,i,j,k;
while(cin>>l>>m>>n)
{ if(l==0&&m==0&&n==0)break;
mem(map);
for(i=0;i<l;i++)
for(j=0;j<m;j++)
{cin>>map[i][j];
for(k=0;k<n;k++)
if(map[i][j][k]=='S')
{sx=i;sy=j;sz=k;}
}
int step=bfs(sx,sy,sz);
if(step)printf("Escaped in %d minute(s).\n",step);
else printf("Trapped!\n");
}
return 0;
}

这倒题主要运用了三维数组,不过和以前的二维数组是一样的,bfs部分也没什么不同。适合初学者!
下面是用dfs()做的不过超时了。。。。。。。。
=============================================================================
这题主要注意 h代表行数 w代表列数
Curling 2.0
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 12951Accepted: 5442

Description

On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is played on an ice game board on which a square mesh is marked. They use only a single stone. The purpose of the game is to lead the stone from the start to the goal with the minimum number of moves.

Fig. 1 shows an example of a game board. Some squares may be occupied with blocks. There are two special squares namely the start and the goal, which are not occupied with blocks. (These two squares are distinct.) Once the stone begins to move, it will proceed until it hits a block. In order to bring the stone to the goal, you may have to stop the stone by hitting it against a block, and throw again.

搜索入门题 - 风未定 - NGUNAUJ
Fig. 1: Example of board (S: start, G: goal)

The movement of the stone obeys the following rules:

  • At the beginning, the stone stands still at the start square.
  • The movements of the stone are restricted to x and y directions. Diagonal moves are prohibited.
  • When the stone stands still, you can make it moving by throwing it. You may throw it to any direction unless it is blocked immediately(Fig. 2(a)).
  • Once thrown, the stone keeps moving to the same direction until one of the following occurs:
    • The stone hits a block (Fig. 2(b), (c)).
      • The stone stops at the square next to the block it hit.
      • The block disappears.
    • The stone gets out of the board.
      • The game ends in failure.
    • The stone reaches the goal square.
      • The stone stops there and the game ends in success.
  • You cannot throw the stone more than 10 times in a game. If the stone does not reach the goal in 10 moves, the game ends in failure.

搜索入门题 - 风未定 - NGUNAUJ
Fig. 2: Stone movements

Under the rules, we would like to know whether the stone at the start can reach the goal and, if yes, the minimum number of moves required.

With the initial configuration shown in Fig. 1, 4 moves are required to bring the stone from the start to the goal. The route is shown in Fig. 3(a). Notice when the stone reaches the goal, the board configuration has changed as in Fig. 3(b).

搜索入门题 - 风未定 - NGUNAUJ
Fig. 3: The solution for Fig. D-1 and the final board configuration

Input

The input is a sequence of datasets. The end of the input is indicated by a line containing two zeros separated by a space. The number of datasets never exceeds 100.

Each dataset is formatted as follows.

the width(=w) and the height(=h) of the board 
First row of the board 
... 
h-th row of the board

The width and the height of the board satisfy: 2 <= w <= 20, 1 <= h <= 20.

Each line consists of w decimal numbers delimited by a space. The number describes the status of the corresponding square.

0vacant square
1block
2start position
3goal position

The dataset for Fig. D-1 is as follows:

6 6 
1 0 0 2 1 0 
1 1 0 0 0 0 
0 0 0 0 0 3 
0 0 0 0 0 0 
1 0 0 0 0 1 
0 1 1 1 1 1

Output

For each dataset, print a line having a decimal integer indicating the minimum number of moves along a route from the start to the goal. If there are no such routes, print -1 instead. Each line should not have any character other than this number.

Sample Input

2 1
3 2
6 6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1
0 1 1 1 1 1
6 1
1 1 2 1 1 3
6 1
1 0 2 1 1 3
12 1
2 0 1 1 1 1 1 1 1 1 1 3
13 1
2 0 1 1 1 1 1 1 1 1 1 1 3
0 0

Sample Output

1
4
-1
4
10
-1

Source

#include<iostream>

using namespace std;
int map[30][30];
int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
int w, h;
int steps, step, sx, sy, ex, ey;
void dfs(int x, int y)
{
 int i;
 if (step>10) return;
 for (i = 0; i<4; i++)
 {
  int ok = 0;
  int nx = x + dir[i][0];
  int ny = y + dir[i][1];
  while (nx<w&&nx >= 0 && ny<h&&ny >= 0 && map[nx][ny]!=1)//尼玛这map[nx][ny]!=1卡了我半天
  {
   ok = 1;
   if (nx == ex&&ny == ey) 
   if (step<steps) steps = step;
   nx += dir[i][0];
   ny += dir[i][1];
  }
  if (map[nx][ny] == 1 && ok)
  {
   step++;
   map[nx][ny] = 0;
   dfs(nx - dir[i][0], ny - dir[i][1]);
   step--; map[nx][ny] = 1;
  }
 }
}
int main()
{
 while (cin >> h>>w&&w&&h)
 {
  memset(map, 0, sizeof(map));
  for (int i = 0; i<w; i++)
   for (int j = 0; j<h; j++)
   {
    cin >> map[i][j];
    if (map[i][j] == 2)
    {
     sx = i; sy = j;
    }
    if (map[i][j] == 3)
    {
     ex = i; ey = j;
    }
   }
  step = 1;
  steps = 100000;
  dfs(sx, sy);
  if (steps>10)cout << "-1" << endl;
  else cout << steps << endl;
 }
 return 0;
}
8月2日又做了一遍这题,,好坑啊。memset()一定要加上,还有全局变量一定要慎用!
poj2676 Sudoku
Sudoku
Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 14558Accepted: 7187Special Judge

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task. 
搜索入门题 - 风未定 - NGUNAUJ

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127

Source

#include<iostream>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
int map[9][9];
bool isfind;
bool row[9][9], col[9][9], sq[9][9];
void print()//输出函数
{
int i, j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
cout << map[i][j] + 1;
cout << endl;
}
}
void dfs(int x, int y)
{
int u = 9 * x + y - 1, i;//用到了一点技巧
if (x ==-1){ isfind = true; print(); }
if (isfind)return;
if (map[x][y] != -1)
{
dfs(u / 9, u % 9);//如果有数直接寻找下一个
return;
}
for (i = 0; i < 9 && !isfind; i++)
{
int k = (x / 3) * 3 + y / 3;
if (!sq[k][i] && !col[x][i] && !row[y][i])
{
sq[k][i] = col[x][i] = row[y][i] = true; map[x][y] = i;
dfs(u / 9, u % 9);
sq[k][i] = col[x][i] = row[y][i] = false; map[x][y] = -1;
}
}
}
int main()
{
int i, j, cas;
cin >> cas;
while (cas--)
{
mem(col);
mem(sq);
mem(row);
mem(map);
char q;
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
{
cin >> q;
map[i][j] = q - '1';
if (q - '0')
{
col[i][q - '1'] = row[j][q - '1'] = sq[(i / 3 * 3 + j / 3)][q - '1'] = true;
}
}
isfind = false;
dfs(8, 8);
}
return 0;
}

总之做这道题题很蹩脚,可能是长时间没做题的缘故吧,后来看了别人的解题报告才弄明白。其实这题很简单的。哎`下回一定要独立思考!哈哈~

Red and Black

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11217    Accepted Submission(s): 7003


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
 

Recommend
Eddy

#include<iostream>
using namespace std;
char map[20][20];
int has[20][20];
int h, w,i,j,sx,sy;
void dfs(int x,int y)
{
if(has[x][y]||x>=h||y>=w||map[x][y]=='#'||x<0||y<0)return ;//跳出当前dfs()层!
has[x][y]=1;
dfs(x+1,y);
dfs(x-1,y);
dfs(x,y-1);
dfs(x,y+1);
}
int main()
{
while(cin>>w>>h&&w&&h)
{memset(map,0,sizeof(map));
memset(has,0,sizeof(has));
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
cin>>map[i][j];
if(map[i][j]=='@')
{
sx=i;sy=j;
}
}
dfs(sx,sy);
int sum=0;
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
if(has[i][j])sum++;
}
cout<<sum<<endl;
}
return 0;
}

重要的是要每访问一个要标记为1这样求和会很好求!(注意横纵坐标)
这道题应该说是很简单的,但在DFS的时候
dfs(x+1,y);
dfs(x-1,y);
dfs(x,y-1);
dfs(x,y+1);
和for(int i=0;i<4;i++)
dfs(x+dir[i][0],y+dir[i][1]) ;
有区别????没搞懂。。。
8月3日更新---当然有区别,4个dfs()是向四个方向进行搜索,而一个dfs()循环4次是有超时。。。
我从hdu的discuss里面看到一个比较好的

#include<cstdio>
#include<iostream>
using namespace std;
int m,n,sum;
int move[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
char pos[30][30];
void dfs(int x ,int y)
{
int i,xx,yy;
sum++;
for(i=0;i<4;i++)
{
xx=x+move[i][0];
yy=y+move[i][1];
if(xx<1 || yy<1 || xx>n || yy>m || pos[xx][yy]=='@' || pos[xx][yy]=='#')
continue;
pos[xx][yy]='@';
dfs(xx , yy);
}
}
int main()
{
int sx,sy,i,j;
while(scanf("%d%d",&m,&n)!=EOF)
{
sum=0;
if(m==0 && n==0) break;
for(i=1;i<=n;i++)
{
getchar();
for(j=1;j<=m;j++)
{
scanf("%c",&pos[i][j]);
if(pos[i][j]=='@')
{
sx=i;sy=j;
}
}
}
dfs(sx,sy);
cout<<sum<<endl;
}
return 0;
}


待更新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值