1. 营救
铁塔尼号遇险了!他发出了求救信号。距离最近的哥伦比亚号收到了讯息,时间就是生命,必须尽快赶到那里。
通过侦测,哥伦比亚号获取了一张海洋图。这张图将海洋部分分化成n*n个比较小的单位,其中用1标明的是陆地,用0标明是海洋。船只能从一个格子,移到相邻的四个格子。
为了尽快赶到出事地点,哥伦比亚号最少需要走多远的距离。
【输入格式】
第一行为n(0<n<=100),下面是一个n*n的0、1矩阵,表示海洋地图;最后一行为四个小于n的整数,分别表示哥伦比亚号和铁塔尼号的位置。
【输出格式】
哥伦比亚号到铁塔尼号的最短距离。
【样例输入】
3
0 0 1
1 0 1
1 0 0
1 1 3 3
【样例输出】
4
#include <iostream> using namespace std; struct node{ int x; int y; int step; }; struct node que[10001]; int map[101][101]; int book[101][101]; //int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; int n,sx,sy,ex,ey,tx,ty,flag = 0; int head = 1,tail = 1; void bfs(){ int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; que[tail].x = sx; que[tail].y = sy; que[tail].step = 0; tail++; book[sx][sy] = 1; while(head < tail){ for(int i = 0;i < 4;i++){ tx = que[head].x + next[i][0]; ty = que[head].y + next[i][1]; if(tx < 1 || tx > n || ty < 1 || ty > n){ continue; } if(map[tx][ty] == 0 && book[tx][ty] == 0){ book[tx][ty] = 1; que[tail].x = tx; que[tail].y = ty; que[tail].step = que[head].step + 1; tail++; } if(tx == ex && ty == ey){ flag = 1; break; } } if(flag == 1){ break; } head++; } } int main(){ cin >> n; for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ cin >> map[i][j]; } } cin >> sx >> sy >> ex >> ey; bfs(); cout << que[tail-1].step << endl; return 0; }
2、抓住那头牛
农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:
1、从X移动到X-1或者X+1,每次移动花费一分钟
2、从X移动到2*X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花费多少时间才能抓住牛?
【输入格式】
两个整数,N和K
【输出样例】
一个整数,农夫抓到牛所要花费的最小分钟数
【样例输入】
5 17
【样例输出】
4
#include <iostream> using namespace std; int n,k,x; bool v[1000001]; int h[1000001][3]; int main(){ cin >> n >> k; h[1][1] = n,v[n] = 1; int head = 0,tail = 1; do{ head++; for(int i = 1;i <= 3;i++){ x = h[head][1]; if(i == 1) x++; if(i == 2) x--; if(i == 3) x *= 2; if(x >= 0 && x <= 100000) if(!v[x] || h[x][2] > h[h[head][1]][2]+ 1){ tail++; h[tail][1] = x; v[x] = 1; h[x][2] = h[h[head][1]][2]+1; } } }while(head < tail); cout << h[k][2] << endl; return 0; }
1、Knight Moves
输入L,代表有L*L的棋盘,输入开始位置的坐标和结束位置的坐标,问一个骑士朝棋盘的八个方向走马字步,从开始坐标到结束坐标可以经过多少步。
【输入格式】
首先输入一个n(0<n<=50),表示测试样例的个数。每个测试样例有三行。第一行是棋盘的大小L(4<=L<=100)。第二行和第三行分别表示马的起始位置和目标位置(0~L-1)。
【输出格式】
马移动的最小步数,起始位置和目标位置相同时输出0。
【样例输入】
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1
【样例输出】
5
28
0
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; int fx[8] = {1,1,2,2,-1,-1,-2,-2}; int fy[8] = {2,-2,1,-1,2,-2,1,-1}; int N,n,sx,sy,ex,ey,h[5000001][3]; int res[51]; bool visited[1001][1001]; int work(int sx,int sy,int ex,int ey){ if((sx == ex) && (sy == ey)) return 0; memset(visited,0,sizeof(visited)); // for(int i = 0;i < 1000;i++){ // for(int j = 0;j < 1000;j++){ // visited[i][j] = 0; // } // } int t = 0,w = 1; h[1][0] = sx,h[1][1] = sy,h[1][2] = 0; do{ t++; int x = h[t][0],y = h[t][1]; for(int i = 0;i < 8;i++){ int X = x + fx[i],Y = y + fy[i]; if(X >= 0 && X < n && Y >= 0 && Y < n && !visited[X][Y]){ w++; h[w][0] = X; h[w][1] = Y; h[w][2] = h[t][2] + 1; visited[X][Y] = 1; if(X == ex && Y == ey) return h[w][2]; } } }while(t < w); } int main(){ cin >> N; for(int i = 1;i <= N;i++){ cin >> n >> sx >> sy >> ex >> ey; res[i] = work(sx,sy,ex,ey); } for(int j = 1;j <= N;j++){ cout <<res[j] << endl; } return 0; }
2. Lake Counting
有一块N*M(1<=N,M<=100)的土地,雨后积起了水,有水标记为‘$’,干燥为‘#’。八连通的积水被认为是连接在一起的。请求出院子里共有多少水洼?(八连通区域指的是从区域内每一位置出发,可通过八个方向,即上、下、左、右、左上、右上、左下、右下这八个方向的移动的组合,在不越出区域的前提下,到达区域内的任意位置。)
【样例输入】
10 12
$########$$#
#$$$#####$$$
####$$###$$#
#########$$#
#########$##
##$######$##
#$#$#####$$#
$#$#$####$$#
#$#$######$#
##$#######$#
【样例输出】
3
#include <iostream> using namespace std; struct node { int x; int y; }; char map[51][51]; struct node que[2501]; int head,tail; int book[51][51]; int sum; int next[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},{1,1},{1,-1},{-1,-1}};//右下左上 int m,n,x,y,tx,ty; void bfs(int x,int y) { sum++; map[x][y] = 0; //初始化队列 head = 1; tail = 1; que[tail].x = x; que[tail].y = y; book[x][y] = 1; tail++; while(head < tail) { for(int k = 0; k < 8; k++) { tx = que[head].x + next[k][0]; ty = que[head].y + next[k][1]; if(tx < 0 || tx >= m || ty < 0 || ty >= n) { continue; } if(map[tx][ty] == '$' && book[tx][ty] == 0) { map[tx][ty] = '#'; book[tx][ty] = 1; que[tail].x = tx; que[tail].y = ty; tail++; } } head++; } } int main() { cin >> m>>n; for(int i = 0; i <m; i++) { for(int j = 0; j < n; j++) { cin >> map[i][j]; } } for(int i = 0; i <m; i++) { for(int j = 0; j < n; j++) { if(map[i][j] == '$') { bfs(i,j); } } } cout <<sum << endl; return 0; }
3、迷宫问题
定义一个二维数组:
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表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
【输入格式】
一个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
【样例输出】
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2 , 4)
(3 , 4)
(4,4)
#include <iostream> using namespace std; int h[37][3],b[26]; int xx[4] = {-1,1,0,0},yy[4] = {0,0,-1,1}; bool a[6][6]; int main(){ int t = 0,w = 1,x,y,k = 0; for(int i = 0;i < 5;i++){ for(int j = 0;j < 5;j++){ cin >> a[i][j]; } } h[1][1] = 0; h[1][2] = 0; a[1][1] = 1; do{ t++; for(int i =0;i < 4;i++){ x = h[t][1] + xx[i]; y = h[t][2] + yy[i]; if(x >= 0 && x < 5 && y >= 0 && y < 5 && a[x][y] == 0){ a[x][y] = 1; w++; h[w][0] = t; h[w][1] = x; h[w][2] = y; if(x == 4 && y == 4) break; } } }while(t < w); while(w > 1){ k++; b[k] = w; w = h[w][0]; } cout << "(0,0)" << endl; for(int i = k;i >= 1;i--) cout << "(" << h[b[i]][1] << "," << h[b[i]][2] << ")" << endl; return 0; }
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号