蓝桥杯题目-仙境诅咒

本文介绍了如何利用DFS和BFS算法解决一个仙境中的诅咒问题,通过深度优先和广度优先遍历,判断两点之间的距离,实现感染扩散的标记过程。
摘要由CSDN通过智能技术生成

链接

仙境诅咒 - 蓝桥云课 (lanqiao.cn)

知识点

DFS,BFS

思路

   解法一

  • DFS算法,不撞南墙不回头的算法,一条道走到底,相当于树的深度遍历对于当前状态
  •  我要把我能感染的给感染,然后跳转到下一个被感染的对象,以此类推直到不能感染为止,此时处于回溯状态,然后再在上一个状态下去感染其他状态,周而复始
  •  如果下一个状态已经被感染了,那么跳过即可。
   DFS代码
#include<bits/stdc++.h>
using namespace std;

const int N = 1e3 + 5;
int n,D;

struct people {
    int x, y;
    bool flag = false;
}People[N];

int getDistince(int x1, int y1, int x2, int y2){
	int a = pow(x1-x2,2);
	int b = pow(y1-y2,2);
    return a + b;
}

bool pd(int x1, int y1, int x2, int y2){
	if(D*D > getDistince(x1, y1, x2, y2))
		return true;
	return false;
}

void DFS(int x, int y){
    for (int i = 1; i <= n; i++){
    	
	    if(People[i].flag)continue;
	    
	    if (pd(x, y, People[i].x, People[i].y)){
	        People[i].flag = true;
	        DFS(People[i].x, People[i].y);
	    }
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> People[i].x >> People[i].y;
    }
    cin >> D;
    People[1].flag = true;
    DFS(People[1].x, People[1].y);
    for (int i = 1; i <= n; i++)
        cout<<People[i].flag<<endl;
    return 0;
}

    解法二

  • 使用BFS搜索算法,从当前状态扩展到其他状态,用一个队列维护当前状态,通过标记是否被诅咒使得每一个节点只遍历一次
  • 根据当前状态与其他状态之间的距离是否合法来判断是否入队(被标记)
  • 当队列为空时,所有可以被标记的都已经被标记完成,此过程相当于对树的层序遍历
   BFS代码
#include<bits/stdc++.h>
using namespace std;

const int N = 1e3+10;
int n,D; 
struct node{
	int x;
	int y;
	bool flag;
}people[N];

queue<node>q;

int getDistince(int x1, int y1, int x2, int y2){
	int a = pow(x1-x2,2);
	int b = pow(y1-y2,2);
    return a + b;
}

bool pd(int x1, int y1, int x2, int y2){
	if(D*D > getDistince(x1, y1, x2, y2))
		return true;
	return false;
}

void BFS(int x,int y){
	q.push(people[1]);
	while(!q.empty()){
		node now = q.front();
		q.pop();
		for(int i = 1;i<=n;i++){
			if(people[i].flag) continue;
			if(pd(x,y,people[i].x,people[i].y)){
				people[i].flag = true;
				q.push(people[i]);
			}
		}
	}
}

int main(){
	cin>>n;
	for(int i = 1;i<=n;i++){
		cin>>people[i].x>>people[i].y;
	}
	cin>>D;
	
	people[1].flag = true;
	BFS(people[1].x,people[1].y);
	
	for(int i = 1;i<=n;i++){
		cout<<people[i].flag<<endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值