CSP认证-非零段划分、脉冲神经网络

文章目录

  • T2-非零段划分
  • T3-脉冲神经网络

T2-非零段划分

好题,模拟潮水和山峰的关系巧解问题

#include 
using namespace std;

typedef pair<int, int> PII;
PII s[100010];
int sum[100010];

int main()
{
    int m;
    scanf("%d", &m);
    for(int i = 1; i <= m; i++)
        scanf("%d%d", &s[i].first, &s[i].second);
    sort(s + 1, s + m + 1);
    for(int i = 1; i <= m; i++)
        sum[i] = sum[i - 1] + s[i].second;

    int maxr = 0, ans;
    for(int i = 1; i <= m; i++)
    {
        if(i > 1 && s[i - 1].first == s[i].first) continue;
        int right_num = sum[m] - sum[i - 1] + (i - 1 - sum[i - 1]);

        if(maxr <= right_num)
        {
            maxr = right_num;
            ans = s[i].first;
        }
    }
    cout << ans << endl;
    return 0;
}

T3-脉冲神经网络

硬卡时间,要用链式前向星建图才可以通过(以下题解66分,改成前向星实现即可通过)

#include 
using namespace std;

static unsigned long nxt = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    nxt = nxt * 1103515245 + 12345;
    return((unsigned)(nxt/65536) % 32768);
}
const int NN = 1e5 + 10, MM = 1e3 + 10, DD = 1e3 + 10;

struct connect
{
    double w;
    int dest, D;
};

double I_cache[1024][1024];
int mod = 0;

struct neuron
{
    double v, u, a, b, c, d;
    int spike_time = 0, r;
    vector<connect> nxt;
}Neuron[MM * 2];

int main()
{
    // freopen("a.in", "r", stdin);
    // freopen("a.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N, S, P, T;
    cin >> N >> S >> P >> T;
    double dt;
    cin >> dt;
    double v, u, a, b, c, d;
    int i = 0, rn, cnt = N;

    while(cin >> rn >> v >> u >> a >> b >> c >> d)
    {
        cnt -= rn;
        while(rn--){
            Neuron[i].v = v, Neuron[i].u = u, Neuron[i].a = a;
            Neuron[i].b = b, Neuron[i].c = c, Neuron[i].d = d;
            Neuron[i].spike_time = 0;
            i++;
        }
        if(cnt == 0) break;
    }
    for(int j = 0; j < P; j++){
        cin >> Neuron[i].r;
        i++;
    }
    int s, t, D;
    double w;
    for(int j = 1; j <= S; j++){
        cin >> s >> t >> w >> D;
        Neuron[s].nxt.push_back({w, t, D});
        mod = max(mod, D + 1);
    }

    // 传播
    for(int j = 1; j <= T; j++)
    {
        // 脉冲源发生脉冲
        for(int k = N; k < N+P; k++)
        {
            int t = myrand();
            if(Neuron[k].r > t)
            {
                for(auto& neighbor:Neuron[k].nxt)
                {
                    int des = neighbor.dest;
                    double w = neighbor.w; int D = neighbor.D;
                    I_cache[(j + D) % mod][des] += w;
                }
            }
        }

        // 计算u, v(神经元)
        for(int k = 0; k < N; k++)
        {
            double vv = Neuron[k].v, uu = Neuron[k].u, I = I_cache[j % mod][k];
            Neuron[k].v = vv + dt*(0.04*vv*vv + 5*vv + 140 - uu) + I;
            Neuron[k].u = uu + dt*Neuron[k].a*(Neuron[k].b*vv - uu);

            if(Neuron[k].v >= 30) {
                // 发放脉冲
                for(auto& neighbor:Neuron[k].nxt)
                {
                    int des = neighbor.dest;
                    double w = neighbor.w; int D = neighbor.D;
                    I_cache[(j + D) % mod][des] += w;
                }
                // 改变u, v
                Neuron[k].spike_time++;
                Neuron[k].v = Neuron[k].c;
                Neuron[k].u += Neuron[k].d;
            }
        }
        memset(I_cache[j % mod], 0, sizeof I_cache[j % mod]);
    }

    int min_time = 2e9, max_time = -2e9;
    double max_v = -2e9, min_v = 2e9;
    for(int j = 0; j < N; j++)
    {
        min_time = min(min_time, Neuron[j].spike_time);
        max_time = max(max_time, Neuron[j].spike_time);
        max_v = max(Neuron[j].v, max_v);
        min_v = min(Neuron[j].v, min_v);
    }
    printf("%.3lf %.3lf\n", min_v, max_v);
    printf("%d %d\n", min_time, max_time);

    return 0;
}

你可能感兴趣的:(算法竞赛笔记,神经网络,算法,c++,数据结构,链表)