解题思路
根据题意,脉冲源的阈值大于随机数时,会向其所有出点发送脉冲
神经元当v>=30时,会向其所有出点发送脉冲,unordered_map <int, vector > ne; //存储神经元/脉冲源的所有出点集合vector
所有脉冲会有一定的延迟,所以使用unordered_map <int, unordered_map <int, double>> I; //存储神经元i的j时刻收到的所有脉冲和
暴力做法就是遍历每一时刻,每一时刻更新神经元和脉冲源,最后统计答案
解题过程
- 一开始用结构体实现,并且没有考虑到一个神经元/脉冲源可能会对多个神经元发出脉冲这个问题,直接按照题意纯模拟,得了16分。。
- 发现了一对多的情况,在结构体中加入了一个vector存储所有的出点,爆内存了,得了33分。。
- 由于每个神经元也不是每一时刻都会收到脉冲,所以稍微改了下,不采用数组存储,采用unorder_map存储,不爆内存了,TLE了。。66分。。
66分暴力版本代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
using namespace std;
const int N = 1010;
static unsigned long nt = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
nt = nt * 1103515245 + 12345;
return((unsigned)(nt/65536) % 32768);
}
struct node
{
int id;
double w;
int D;
};
double v[N], u[N], a[N], b[N], c[N], d[N];
unordered_map <int, vector <node>> ne;
unordered_map <int, unordered_map <int, double>> I;
int sum[N];
int r[2 * N];
int main()
{
int n, s, p, t;
cin >> n >> s >> p >> t;
double dt;
cin >> dt;
int rn;
for (int i = 0; i < n; i += rn) //0 ~ n - 1神经元
{
cin >> rn;
double vv, uu, aa, bb, cc, dd;
cin >> vv >> uu >> aa >> bb >> cc >> dd;
for (int j = i; j < i + rn; j ++)
{
v[j] = vv;
u[j] = uu;
a[j] = aa;
b[j] = bb;
c[j] = cc;
d[j] = dd;
}
}
for (int i = n; i < n + p; i ++) //n ~ n + p - 1脉冲源
{
cin >> r[i];
}
for (int i = 0; i < s; i ++) //突触
{
int bn, ed;
double w;
int D;
cin >> bn >> ed >> w >> D;
struct node t = {ed, w, D};
ne[bn].push_back(t);
}
for (int i = 1; i <= t; i ++) //遍历每一时刻
{
for (int j = 0; j < n; j ++) //更新神经元
{
double pv = v[j], pu = u[j];
v[j] = pv + dt * (0.04 * pv * pv + 5.0 * pv + 140.0 - pu) + I[j][i];
u[j] = pu + dt * a[j] * (b[j] * pv - pu);
if (v[j] >= 30.0)
{
v[j] = c[j];
u[j] += d[j];
sum[j] ++;
for (auto x : ne[j]) //向所有出点释放脉冲
{
int id = x.id;
double w = x.w;
int D = x.D;
I[id][i + D] += w;
}
}
}
for (int j = n; j < n + p; j ++) //脉冲源释放脉冲
{
int x = myrand();
if (r[j] > x) //r大于随机值
{
for (auto x : ne[j]) //向所有出点释放脉冲
{
int id = x.id;
double w = x.w;
int D = x.D;
I[id][i + D] += w;
}
}
}
}
double r1 = v[0], r2 = v[0];
int s1 = sum[0], s2 = sum[0];
for (int i = 1; i < n; i ++) //得到答案
{
r1 = min(r1, v[i]);
r2 = max(r2, v[i]);
s1 = min(s1, sum[i]);
s2 = max(s2, sum[i]);
}
printf("%.3lf %.3lf\n", r1, r2);
cout << s1 << " " << s2;
return 0;
}