NEUQ-ACM 必做题 week6

文章介绍了四个编程题目,分别涉及广度优先搜索(BFS)在电梯问题中的应用,马的遍历中使用数组记录步数,利用并查集解决奶酪连接问题,以及填充颜色的深度优先搜索。这些题目展示了在IT技术中解决路径问题和数据结构的应用。
摘要由CSDN通过智能技术生成

P1135 奇怪的电梯

1.与视频里的bfs例题一样,每一次分为上楼与下楼两个选择,判断后入队

2.用vis[i]标记到过的楼层优化

#include <bits/stdc++.h>
using namespace std;
int n,start,end;
int a[205],vis[202];
struct pos{ 
	int level; //目前的楼层
	int step; //第几步
};
void bfs(); 
int main(){
	while(scanf("%d",&n)==1){
		if (n==0) break;
		scanf("%d%d",&start,&end);
		for (int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			vis[i]=0;
		}
		bfs();
	}
	return 0;
} 

void bfs(){     
	pos cur,nex;
	cur.level=start;
	cur.step=0;
	queue<pos>qu;
	qu.push(cur);
	vis[start]=1;
	while (!qu.empty()){
		cur=qu.front();
		qu.pop();
		if (cur.level==end){
			cout<<cur.step;
			return;
		}
		nex.level=cur.level+a[cur.level];
		nex.step=cur.step+1;
		if (nex.level<=n){
			if(vis[nex.level]==0){
				vis[nex.level]=1;
				qu.push(nex);
			}
		}
		nex.level=cur.level-a[cur.level];
		nex.step=cur.step+1;
		if (nex.level>=1){
			if(vis[nex.level]==0){
				vis[nex.level]=1;
				qu.push(nex);
			}
		}
	}
	cout<<"-1"<<endl;
	return;
}

P1443 马的遍历

1.每一次马都有八个跳法,先造两个dx与dy数组记录

2.用f[i][j]记录该位置的步数

#include <bits/stdc++.h>
using namespace std;
int f[450][450],vis[450][450];
struct pos{
	int a;
	int b;
};
int main(){
	int dx[8]={-1,-2,-2,-1,1,2,2,1};
	int dy[8]={2,1,-1,-2,2,1,-1,-2};
	int n,m,x,y;
	cin>>n>>m>>x>>y;
	pos cur,nex;
	cur.a=x; cur.b=y;
	queue<pos> q;
	memset(f,-1,sizeof(f));
	memset(vis,0,sizeof(vis));
	f[x][y]=0;vis[x][y]=1;
	q.push(cur);
	while (!q.empty()){
		int xx=q.front().a,yy=q.front().b;
		q.pop();
		for (int i=0;i<8;i++){
			nex.a=xx+dx[i],nex.b=yy+dy[i];
			if (nex.a<1 ||nex.a>n||nex.b<1||nex.b>m||vis[nex.a][nex.b]) { //跑出棋盘或者重复到同一位置都直接跳过这个循环
				continue;	
			}else{
				vis[nex.a][nex.b]=1;
				q.push(nex);
				f[nex.a][nex.b]=f[xx][yy]+1; 
		}
	}
}
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			printf("%-5d",f[i][j]);
		}
		cout<<endl;
	}
	return 0;
}

P3958 [NOIP2017 提高组] 奶酪

1.用到并查集的算法

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int f[1010];
int find(int x){
	if (f[x]!=x) return f[x]=find(f[x]);
	return f[x];
} //查找
ll dis(ll x,ll y,ll z,ll x1,ll y1,ll z1){
	return (x-x1)*(x-x1)+(y-y1)*(y-y1)+(z-z1)*(z-z1);
}
ll x[100010],y[100010],z[10010];
int f1[100010],f2[100010];
int main(){
	int t,n;
	ll r,h;
	cin>>t;
	for (int i=1;i<=t;i++){
		cin>>n>>h>>r;
		int cnt1=0,cnt2=0;
		for (int j=1;j<=n;j++){
			f[j]=j; //初始化
		}
		for (int j=1;j<=n;j++){
			cin>>x[j]>>y[j]>>z[j];
			if (z[j]+r>=h){ //与顶部相交的奶酪
				cnt1+=1;
				f1[cnt1]=j;
			} 
			if (z[j]-r<=0){ //与底部相交的奶酪
				cnt2+=1;
				f2[cnt2]=j;
			}
			for (int k=1;k<j;k++){
				if (dis(x[j],y[j],z[j],x[k],y[k],z[k])<=4*r*r){
					int a1=find(j); 
					int a2=find(k);
					if (a1!=a2) f[a1]=a2; //两圆相切或相交并入同一集合
				}
			}
		}
		int cn=0;
		for (int j=1;j<=cnt1;j++){
			for (int k=1;k<=cnt2;k++){
				if (find(f1[j])==find(f2[k])){ //若与底部和顶部都相交的圆都在同一集合,则相连
					cn=1;
					break;
				}
			}
			if (cn==1) break;
		}
		if (cn==1) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
} 

P1162 填涂颜色

#include <bits/stdc++.h>
using namespace std;
int a[40][40],b[40][40];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int n,i,j;
void dfs(int p,int q){
	if (p<0||p>n+1||q<0||q>n+1||a[p][q]!=0) return;
	a[p][q]=1; 
	for (int i=0;i<4;i++){
		dfs(p+dx[i],q+dy[i]);
	}
}
int main(){
	cin>>n;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cin>>b[i][j];
			if (b[i][j]==0) a[i][j]=0;
			else a[i][j]=2;
		}
	}
	dfs(0,0);
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			if (a[i][j]==0){
				cout<<2<<" ";
			}else{
				cout<<b[i][j]<<" ";
			}
		}
		cout<<endl;
	} 
	return 0;
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值