D3考试题

献给阿尔吉侬的花束

题目描述

阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。

 迷宫用一个R×C的字符矩阵来表示。字符S表示阿尔吉侬所在的位置,字符E表示奶酪所在的位置,字符#表示墙壁,字符.表示可以通行。阿尔吉侬在1个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。

输入描述

第一行是一个正整数T(1 ≤ T ≤ 10),表示一共有T组数据。 

每一组数据的第一行包含了两个用空格分开的正整数R和C(2 ≤ R, C ≤ 200),表示地图是一个R×C的矩阵。 

接下来的R行描述了地图的具体内容,每一行包含了C个字符。字符含义如题目描述中所述。保证有且仅有一个S和E。

输出描述

对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。每组数据的输出结果占一行。

样例输入
3
3 4
.S..
###.
..E.
3 4
.S..
.E..
....
3 4
.S..
####
..E.
样例输出
5
1
oop!
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<queue>
#include<algorithm>
using namespace std;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int t,n,m,c,r,cc,rr,f;
char a[220][220];
int vis[220][220],step[220][220];
void bfs(){
	queue<int> qx,qy;
	qx.push(c);
	qy.push(r);
	vis[c][r]=1;
	while(qx.empty()==0){
		int x=qx.front();
		int y=qy.front();
		qx.pop();
		qy.pop();
		if(x==cc&&y==rr){
			cout<<step[x][y]<<endl;
			f=1;
			return ;
		}
		for(int i=0;i<4;i++){
			int nx=x+dx[i];
			int ny=y+dy[i];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&vis[nx][ny]==0&&a[nx][ny]!='#'){
				qx.push(nx);
				qy.push(ny);
				vis[nx][ny]=1;
				step[nx][ny]=step[x][y]+1;
			}
		}
	}
}
int main(){
	cin>>t;
	while(t--){
		f=0;
		cin>>n>>m;
		memset(vis,0,sizeof vis);
		memset(step,0,sizeof step);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				cin>>a[i][j];
				if(a[i][j]=='S'){
					c=i;
					r=j;
				}
				if(a[i][j]=='E'){
					cc=i;
					rr=j;
				}
			}
		}
		bfs();
		if(f==0){
			cout<<"oop!";
		}
	}
	return 0;
}

细胞

题目描述

一矩形阵列由数字 0 到  9 组成,数字 1 到 9 代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如: 阵列

4 10 

0234500067 

1034560500 

2045600671 

0000000089 

有 4 个细胞。

输入描述

第一行为矩阵的行 n 和列 m (1≤n,m≤100); 

下面为一个  n×m 的矩阵。

输出描述

细胞个数。

样例输入
4 10
0234500067
1034560500
2045600671
0000000089
样例输出
4
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<queue>
#include<algorithm>
#define N 105
#define ll long long
using namespace std;
int n,m;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int cnt;
char a[N][N];
bool vis[N][N];
void dfs(int x,int y){
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&vis[nx][ny]==0&&a[nx][ny]!='0'){
			dfs(nx,ny);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]!='0'&&vis[i][j]==0){
				cnt++;
				dfs(i,j);
			}
		}
	}
	cout<<cnt;
	return 0;
}

树的权值深度

题目描述

求树的各个节点的权值有一种方法是自上而下统计信息。起初,我们已知根节点s的的权值深度为0。若某个节点x的权值深度为d[x],x与它的某个子节点y之间的边的权值为z(1<=z<=10000)则它的子节点y的权值深度d[y]=d[x]+z,现在给你一棵树,让你输出每个节点的权值深度。

输入描述

第一行,两个整数n(1<=n<=200000),s,n表示树的节点的个数,s表示树的根节点的编号。
接下来的n-1行中,每行有三个整数x,y,z,表示x和y有一条边 且权值为z。

输出描述

输出一行,表示每个节点的权值深度,用空格间隔

样例输入
9 1
1 2 3
1 7 2
1 4 6 
2 8 7
2 5 1212
4 6 10000
4 3 1
3 9 12
样例输出
0 3 7 6 1215 10006 2 10 19
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<queue>
#include<algorithm>
#define N 200020
using namespace std;
int n,s;
int nx[2*N],h[N],v[2*N],val[2*N],tot=-1;
int vis[2*N],d[2*N];
void add(int a,int b,int c){
	++tot;
	v[tot]=b;
	val[tot]=c;
	nx[tot]=h[a];
	h[a]=tot;
}
void dfs(int x){
	vis[x]=1;
	for(int i=h[x];~i;i=nx[i]){
		int y=v[i];
		int z=val[i];
		if(vis[y]==0){
			d[y]=d[x]+z;
			dfs(y);
		}
	}
}
int main(){
	memset(h,-1,sizeof h);
	cin>>n>>s;
	for(int i=1;i<n;i++){
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	d[s]=0;
	dfs(s);
	for(int i=1;i<=n;i++){
		cout<<d[i]<<" ";
	}
	return 0;
}

营救

题目描述

铁塔尼号遇险了!他发出了求救信号。距离最近的哥伦比亚号收到了讯息,时间就是生命,必须尽快赶到那里。
通过侦测,哥伦比亚号获取了一张海洋图。这张图将海洋部分分成了 n*n 个比较小的单位,其中用1标明的是陆地,用0标明是海洋。船只能从一个格子,移到相邻的四个格子。
为了尽快赶到出事地点,哥伦比亚号最少需要走多远的距离。

输入描述

第一行为n,下面是一个n*n 的0、1矩阵,表示海洋地图 ,
最后一行为四个小于等于n的整数,分别表示哥伦比亚号和铁塔尼号的位置。

输出描述

哥伦比亚号到铁塔尼号的最短距离,答案精确到整数。

样例输入
3 
001
101 
100 
1 1 3 3
样例输出
4
提示

N<=1000

代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<queue>
#include<algorithm>
#define N 105
#define ll long long
using namespace std;
int n,vis[1005][1005],c,r,cc,rr,step[1005][1005];
char a[1005][1005];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void bfs(){
	queue<int> qx,qy;
	qx.push(c);
	qy.push(r);
	vis[c][r]=1;
	while(qx.empty()==0){
		int x=qx.front();
		int y=qy.front();
		qx.pop();
		qy.pop();
		if(x==cc&&y==rr){
			cout<<step[x][y];
			break;
		}
		for(int i=0;i<4;i++){
			int nx=x+dx[i];
			int ny=y+dy[i];
			if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&vis[nx][ny]==0&&a[nx][ny]=='0'){
				qx.push(nx);
				qy.push(ny);
				vis[nx][ny]=1;
				step[nx][ny]=step[x][y]+1;
			}
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>a[i][j];
		} 
	}
	cin>>c>>r>>cc>>rr;
	bfs();
	return 0;
}

爱丽丝

题目描述

爱丽丝生活在一个扁平的星球上,该星球可以建模为大小为n×n的正方形网格,行和列的范围为1到n。 我们用有序对(r,c)表示行r和列c的交点处的网格。 网格中的每个单元都是土地或水。

爱丽丝居住在陆地单元(r1,c1)中。 她希望旅行到陆地单元(r2,c2)。 在任何时候,她都可以沿四个方向之一(即上,下,左或右)移动到与其所在位置相邻的一个单元中。

不幸的是,爱丽丝不能游泳,除了步行以外没有其他可行的交通工具(也就是说,她只能在陆地上行走)。 结果,爱丽丝可能走不到终点。

为了帮助爱丽丝,您计划在一些两个陆地单元之间最多创建一个隧道。 该隧道将允许Alice在两个端点之间自由行进。 确实,创建隧道是一项艰巨的工作:在单元(rs,cs)和(rt,ct)之间创建隧道的成本为(rs-rt)^ 2+(cs-ct)^ 2。(^2是平方的意思)

现在,您的任务是找到最多创建一个隧道的最小可能成本,以便Alice可以从(r1,c1)移至(r2,c2)。 如果不需要创建隧道,则成本为0。

输入描述

第一行包含一个整数n(1≤n≤50)-正方形网格的宽度。

第二行包含两个以空格分隔的整数r1和c1(1≤r1,c1≤n)-表示Alice所在的单元格。

第三行包含两个以空格分隔的整数r2和c2(1≤r2,c2≤n)-表示爱丽丝希望移动到的单元格。

接下来的n行中的每行包含n个字符的字符串。 如果(i,j)是陆地,则第i条这样的线(1≤i,j≤n)的第j个字符为0,如果(i,j)为水,则第i个字符为1。

保证(r1,c1)和(r2,c2)是陆地。

输出描述

打印一个整数,该整数是创建最多一个隧道的最小可能成本,以便Alice可以从(r1,c1)到达(r2,c2)。

样例输入
5
1 1
5 5
00001
11111
00111
00110
00110
样例输出
10
提示

样例输入1

3

1 3

3 1

010

101

010

样例输出1

8

代码

(笑死,直接输出样例都能得分)

暂无

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值