(有帮助的话记得给卑微的小博主一个红sai的手手哦!!!)
7-8 印度大壶节 (25 分)
印度2021年4月为何突然疫情大爆发,一组照片的曝光让人们注意到印度的大壶节。每6年在印度就会举行一次持续时间达6个星期的大壶节,四个地方每地一次。该节的影响力非常巨大,每次举办活动都不会有少于7000万人的信徒来参加,在恒河洗澡是大壶节的重要活动之一。
参加印度大壶节的人群来自印度全国各地,参加活动的人员除了在恒河洗澡,就是每天坐在临时帐篷里进行冥想。因为活动人群太密集导致病毒传播很快、范围很广,所以印度疫情突然加重,氧气和床位十分稀缺,疫苗更是可望不可求,短时间内摆脱疫情危机只能是幻想。 数量太大,我们无法对那么大的数据进行处理,只能小规模模拟一下大壶节对新冠病毒传播的影响。
输入格式:
首先输入五个整数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;
}
}
}