又到了一周一次的题解时间
#include <bits/stdc++.h>
using namespace std;
struct man {
vector<int> tudi;
} mans[100001];
int main()
{
int n;
double z, r;
cin >> n >> z >> r;
r *= 0.01;
double fi[n + 1] = {z, 0};
double sum = 0;
queue<pair<int, int>> que;
for(int i = 0;i < n;i ++)
{
mans[i].tudi.clear();
int k;
cin >> k;
if(k == 0)
{
int pl;
cin >> pl;
// cout << "Push " << i << " " << pl << endl;
pair<int, int> np(i, pl);
que.push(np);
}
// cout << "i : " << i << " , fi = " << fi[i] << endl;
// sum += fi[i];
for(int j = 0;j < k;j ++)
{
int num;
cin >> num;
mans[i].tudi.push_back(num);
}
if(k != 0)
{
// cout << "Push " << i << " " << -1 << endl;
pair<int, int> np(i, -1);
que.push(np);
}
}
while(!que.empty())
{
int id = que.front().first;
int mod = que.front().second;
// cout << "Now at " << id << " " << mod << endl;
if(fi[id] == 0)
{
pair<int, int> np(id, mod);
que.push(np);
} else {
if(mod == -1)
{
for(int i = 0;i < mans[id].tudi.size();i ++)
{
fi[mans[id].tudi[i]] = fi[id] * (1.0 - r);
// cout << id << " " << mans[id].tudi[i] << " " << fi[mans[id].tudi[i]] << endl;
}
} else {
fi[id] *= mod;
sum += fi[id];
}
// cout << fi[id] << endl;
}
que.pop();
}
// cout << sum << endl;
cout << (long long)sum << endl;
return 0;
}
刚开始写是想要边输入边处理的,发现不行
因为可能会出现输入的时候这个人还没有被师傅教授,意味着他的武力值(暂且这么叫)为零,那么他教出来的徒弟也都是零武力值的,这不是我们想要的,所以我放了个队列存了pair,pair中存的就是这个人的武力值和他是否得道(有没有武力值倍数),又放了一个结构体来存不同的人他们的徒弟(使用pair+vector容器,当然用stack、queue容器都可以,这里没有严格的顺序限制)。
输入的时候,把相关信息放入到容器中,尤其是存这个人的编号和是否得道到queue中,这是我们后续遍历处理需要的。
信息输入完成后,我们得到了一个存好的queue,接下来就是处理这个queue了。我定义了一个sum,用于存储得道者的武力值总和。
每次看队列最前方的人,如果他的编号对应的武力值,即他的武力值为零,那么这个人我就等下再处理,即把原来的信息原封不动的重新排入queue尾,继续下一个处理,如果这个人武力值不为零,就让他去教授他的徒弟(如果是得道者,那么他的得道数不为-1,就把他的武力值先乘以一个得道倍数,然后加到sum里),然后就可以让他滚蛋了(从queue中提出不重新排入),这样我们就成功分别处理了不同情况。这样子循环往复,到最后我们的队列就变成空的了。
队列为空,意味着我们的处理完毕。输出sum即可。
说实话,很多题目都是半对半错,只拿了部分的分数,然后上周也没有CF赛事,能写题解的题目就很少... ...把做的题目列表附上吧
就很痛苦反正。
但是这周除了写题最重要的一点就是学JAVA。这周把环境基本配置好了,每天也都有看《JAVA疯狂讲义》然后做高亮批注、夹书签。
下周如果赛事不忙的话估计重心都在JAVA上了,毕竟还有个写项目的任务,而我JAVA都还没有看完。