pta 7-8 印度大壶节 (25 分)

(有帮助的话记得给卑微的小博主一个红sai的手手哦!!!)

7-8 印度大壶节 (25 分)

印度2021年4月为何突然疫情大爆发,一组照片的曝光让人们注意到印度的大壶节。每6年在印度就会举行一次持续时间达6个星期的大壶节,四个地方每地一次。该节的影响力非常巨大,每次举办活动都不会有少于7000万人的信徒来参加,在恒河洗澡是大壶节的重要活动之一。

111.jpg

参加印度大壶节的人群来自印度全国各地,参加活动的人员除了在恒河洗澡,就是每天坐在临时帐篷里进行冥想。因为活动人群太密集导致病毒传播很快、范围很广,所以印度疫情突然加重,氧气和床位十分稀缺,疫苗更是可望不可求,短时间内摆脱疫情危机只能是幻想。 数量太大,我们无法对那么大的数据进行处理,只能小规模模拟一下大壶节对新冠病毒传播的影响。

输入格式:

首先输入五个整数N, M, D, IT, DT,分别表示参与人的数量(不超过1000),已经感染新冠病毒的人的数量,安全距离,病毒感染时间和活动持续时间, 如果两个人之间的距离大于等于D,则认为他们之间不会发生感染,如果两个人之间的距离小于D,其中一个人感染了病毒,并且相处时间大于IT的话,则另一个人会被感染。很显然,活动持续得越久,感染人数就越多。

之后N行,分别输入参与人的坐标x和y,x和y都是0到1000之间的整数,中间用空格隔开,我们对参与人按0——N-1的顺序编号。随后是M行数据,分别输入参与人编号,表示活动开始时该人已经感染了新冠病毒。

输出格式:

请在一行中输出活动结束之后还没被感染的人的数量,以及其余人最快被全部感染的时间,中间用空格隔开。

输入样例:

在这里给出一组输入。例如:

3 1 3 10 20
0 0
1 0
0 3
0

结尾无空行

输出样例:

在这里给出相应的输出。例如:

1 10

结尾无空行

样例说明:(0,0)和(1,0)之间距离小于3,(0,0)、(1,0)与(3,0)之间距离大于等于3,而(0,0)初始已感染。传播时间是10,持续时间20,病毒可以传播2轮,但是由于(0,3)不在传播范围内,所以(1,0)被传染之后就不再继续传染了。 所以结束的时候(0,3)幸存了,而传播只花了10的时间。

PS:虽然我们以吐槽的口吻来谈论印度疫情,但更多的应该是“哀其不幸,怒其不争”的心态,毕竟,疫情统计里,变化的不是数字,而是生命,人生不易,我们该尊重每一条生命!

本题和另一道感染题类似(可以看一下思路更清晰:(23条消息) pta 感染,结构体队列的使用_菜菜记笔记的博客-CSDN博客

 本题代码(思路注释中给出):

#include<bits/stdc++.h>
using namespace std;
typedef struct nnn {
	int x, y;
	int f = 0;//是否被处理过感染
}s;
s D,dd[10000];
queue<s>a;//存入感染者
vector<s>b;//存入所有人员
int m, n, d, it, dt;
bool flag = true;
int sump =0 ;
void Find(int x1, int y1) {//找当前坐标可以感染的所有人进行感染
	vector<s>::iterator iter;
	for (iter = b.begin(); iter != b.end(); iter++) {
		if (iter->f == 0&& dt>=it) {//符合感染条件
			//两点之间的距离计算:
			double num = pow(x1 - iter->x, 2) + pow(y1 - iter->y, 2);
			num = sqrt(num);
			if (num < d){ //感染
				iter->f = 1;
				flag = false;
				D.x = iter->x, D.y = iter->y;
				a.push(D);//新感染者
				sump++;
			}
		}
	}
}

int main() {
	cin >> n >> m >> d >> it >> dt;
	int tt = dt;
	int xx, yy;
	for (int i = 0; i < n; i++) {
		cin >> xx >> yy;
		dd[i].x = xx;
		dd[i].y = yy;
	}
	for (int i = 0; i < m; i++) {
		cin >> xx;
		D.x = dd[xx].x; D.y = dd[xx].y;
		dd[xx].f = 1;//记录被感染了
		a.push(D);//感染者入队
		sump++;
	}
	for (int i = 0; i < n; i++) {
		D.x = dd[i].x, D.y = dd[i].y, D.f = dd[i].f;
		b.push_back(D);
	}
	while (1) {//一轮一轮查找,一轮一轮感染,直到无未感染着或无法再继续感染
		flag = true;
		int lens = a.size();
		for (int i = 0; i < lens; i++) {
			D = a.front();
			Find(D.x,D.y);//对该感染者进行处理
			a.pop();
		}
		if (!flag) {//成功感染的话
			//(感染成功才算时间)
			dt -= it;
		}
		else {//直接退出
			cout << n - sump << " " << tt - dt;
			return 0;
		}
		if (!dt || a.empty()) {//没时间感染了就输出
			cout << n - sump << " " << tt-dt; 
			return 0;
		}
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值