题意
按照题目要求模拟脉冲神经网络
数据范围:$\begin{matrix}&T&N&S&P&D\\1&\le10^2&\le10^2&\le10^2&\le10^2&\le10^2\\2&\le10^3&\le10^3&\le10^3&\le10^3&\le10^3\\3&\le10^5&\le10^3&\le10^3&\le10^3&\le10\end{matrix}$
题解
$66\%$数据
按照题意进行模拟- 枚举$[0,T]$每个时刻,这里应为一个外层循环
- 对脉冲源进行处理:通过$r$参数判断是否会发射脉冲
- 对神经元进行处理:通过$v_k$判断是否会发射脉冲;如果发射脉冲,则更新$u_k,v_k$
$100\%$数据
由于取模操作比较费时,会导致上述算法TLE
所以提前取模以应对卡常
同时注意存图时使用链式前向星
代码#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int INF=1e9; const int N=1000+10; int n,s,p,t,cnt,mod; int r[N],tot[N],head[N<<1];; double dt; double v[N],u[N],a[N],b[N],c[N],d[N],I[N][N]; struct Edge{ int nxt,to,d; double w; }e[N<<1]; static unsigned long Next=1; int myrand(void){ Next=Next*1103515245+12345; return((unsigned)(Next/65536)%32768); } void add(int u,int v,double w,int d){ e[cnt]=Edge{head[u],v,d,w}; head[u]=cnt++; } void launch(int u,int t){ for(int i=head[u];~i;i=e[i].nxt) I[(t+e[i].d)%mod][e[i].to]+=e[i].w; } int main(){ memset(head,-1,sizeof(head)); scanf("%d%d%d%d",&n,&s,&p,&t); scanf("%lf",&dt); int sum=0,rn; double vv,uu,aa,bb,cc,dd; for(;sum<n;){ scanf("%d%lf%lf%lf%lf%lf%lf",&rn,&vv,& uu,&aa,&bb,&cc,&dd); for(int i=sum;i<n;i++){ v[i]=vv,u[i]=uu; a[i]=aa,b[i]=bb,c[i]=cc,d[i]=dd; } sum+=rn; } for(int i=0;i<p;i++) scanf("%d",&r[i]); int ss,tt,ddd; double ww; for(int i=0;i<s;i++){ scanf("%d%d %lf %d",&ss,&tt,&ww,&ddd); add(ss,tt,ww,ddd); mod=max(mod,ddd); } mod++; int time=1,ct; double vk,uk,ik; for(;time<=t;){ ct=time%mod; for(int i=0;i<p;i++) if(r[i]>myrand()) launch(i+n,ct); for(int i=0;i<n;i++){ ik=I[ct][i]; I[ct][i]=0; vk=v[i],uk=u[i]; v[i]=vk+dt*(0.04*vk*vk+5*vk+140-uk) +ik; u[i]=uk+dt*a[i]*(b[i]*vk-uk); if(v[i]>=30){ launch(i,time); tot[i]++; v[i]=c[i],u[i]+=d[i]; } } time++; } double vmin=INF,vmax=-INF; int cmin=INF,cmax=-INF; for(int i=0;i<n;i++){ vmin=min(vmin,v[i]); vmax=max(vmax,v[i]); cmin=min(cmin,tot[i]); cmax=max(cmax,tot[i]); } printf("%.3lf %.3lf\n",vmin,vmax); printf("%d %d\n",cmin,cmax); return 0; }
想想你的文章写的特别好https://www.ea55.com/