• 【某次ks】20200512


    <前言>

    虽然全程睡觉,但是考得不错。

    今早昨晚多晚睡我也就不说了,总之很困。就写了T1正解。


    考试过程

    T1

    第一反应干草炸弹。

    然后一个二分,判定的时候人傻了。直接计算不就好了写啥二分。

    复杂度一算,单走一个树状数组,傻*。

    然后睡了一场比赛。

    T2

    一开始题目出锅没看

    后来不想看了

    题解上一个二维最短路,s*。

    T3

    预处理+(dp),当时我tm直接睡着。

    睡着前写了一个(dfs),实测5分;

    T4

    一看路径相关,反手一个点分。

    然后发现有同色重复路径。

    懒得管了,直接交,然后一分都没有。


    考完之后我去接校车,结果等了半天发现不是今天(???)

    然后就吃饭回寝

    爽啦


    Solution

    [20200512普转提]T1 vr

    大意

    (N)个病毒,每个位置(x_i),生命值(h_i),每次攻击范围([x-d,x+d])范围内病毒,伤害为(W),则最少几次杀死所有病毒。

    Solution

    因为要消灭所有病毒,最左边的病毒一定要被消灭,不妨直接以最左边病毒位置为左端点释放攻击。

    这是个显而易见的贪心,然后直到消灭所有病毒即可。

    (Code:)

    #include<bits/stdc++.h>
    #define N 200010
    #define int long long
    using namespace std;
    int n, d, k;
    struct node
    {
        int x, h;
    } a[N] = {};
    int c[N] = {};
    void inc(int x, int v)
    {
        for(; x <= N - 10; x += x & (-x))
            c[x] += v;
    }
    int ask(int x)
    {
        int sum = 0;
        for(; x; x -= x & (-x))
            sum += c[x];
        return sum;
    }
    inline int read()
    {
        int s = 0, w = 1;
        char c = getchar();
        while((c < '0' || c > '9') && c != '-')
            c = getchar();
        if(c == '-')w = -1, c = getchar();
        while(c <= '9' && c >= '0')
            s = (s << 3) + (s << 1) + c - '0', c = getchar();
        return s * w;
    }
    
    inline bool cmp(node x, node y)
    {
        return x.x < y.x;
    }
    
    signed main()
    {
        freopen("vr.in", "r", stdin);
        freopen("vr.out", "w", stdout);
        n = read();
        d = read();
        k = read();
        for(int i = 1; i <= n; ++i)
            a[i].x = read(), a[i].h = read();
        sort(a + 1, a + n + 1, cmp);
        int tag = 1;
        long long sum = 0;
        for(int i = 1; i <= n; ++i)
        {
            int add = ask(i);
            if(a[i].h + add * k <= 0)continue;
            long long dec = (a[i].h + add * k + k - 1) / k;
            while(a[tag].x <= a[i].x + 2 * d && tag <= n)
                ++tag;
            inc(i, -dec);
            inc(tag, dec);
            sum += dec;
        }
        printf("%lld
    ", sum);
        return 0;
    }
    

    [20200512普转提]T2 旅行花费

    大意

    (n)个城市,它们由(m)条双向道路连接,保证它们能够彼此到达。

    (i)条道路连接(u_i,v_i),需要花费(x_i)个银币,耗费(t_i)秒的时间。每个城市处都有兑换银币处,第(i)个城市中你可以每次用(1)个金币兑换(c_i)个银币,可以兑换无限次,不过兑换(1)次需要花费(d_i)秒的时间。

    你一开始在(1)号城市,有(s)个银币和无限多的金币,求到其它城市需要耗费的最小时间。

    Solution

    我们发现(x_ileq 50)(Mleq 100)所以银币最多不过5000,再多也没用。

    直接设置limit,然后把(位置,所剩银币)作为一个点去做二维最短路。

    注意有很多细节比如如何获得答案?银币数的维护?

    #include<bits/stdc++.h>
    #define N 5010
    #define fi first
    #define se second
    #define ll long long
    #define mmp(x,y) make_pair(x,y)
    using namespace std;
    
    int n, m, s;
    int c[N] = {}, d[N] = {};
    
    inline int read()
    {
        int s = 0, w = 1;
        char c = getchar();
        while((c < '0' || c > '9') && c != '-')
            c = getchar();
        if(c == '-')w = -1, c = getchar();
        while(c <= '9' && c >= '0')
            s = (s << 3) + (s << 1) + c - '0', c = getchar();
        return s * w;
    }
    
    ll dis[55][N] = {};
    int vis[55][N] = {};
    
    struct Graph
    {
        int net[N << 1], w[N << 1];
        int to[N << 1], ti[N << 1];
        int fl[N], len;
        inline void inc(int x, int y, int z, int t)
        {
            to[++len] = y;
            w[len] = z;
            ti[len] = t;
            net[len] = fl[x];
            fl[x] = len;
        }
    } G;
    priority_queue<pair<ll, pair<int, int> > >q;
    void DJ(void)
    {
        memset(vis, 0, sizeof(vis));
        memset(dis, 0x3f, sizeof(dis));
        dis[1][min(s, 5000)] = 0;
        q.push(mmp(-dis[1][min(s, 5000)], mmp(1, min(s, 5000))));
        while(!q.empty())
        {
            int t = q.top().se.fi;
            int s = q.top().se.se;
            q.pop();
            if(vis[t][s])continue;
            vis[t][s] = 1;
            if((dis[t][s] + d[t] < dis[t][min(s + c[t], 5000)]))
            {
                dis[t][min(s + c[t], 5000)] = (dis[t][s] + d[t]) * 1LL;
                q.push(mmp(-dis[t][min(5000, s + c[t])], mmp(t, min(5000, s + c[t]))));
            }
            for(int i = G.fl[t]; i; i = G.net[i])
            {
                int v = G.to[i], z = G.w[i], ti = G.ti[i];
                if(s < z)continue;
                if(dis[t][s] + ti < dis[v][s - z])
                {
                    dis[v][s - z] = 1LL * (dis[t][s] + ti);
                    q.push(mmp(-dis[v][s - z], mmp(v, s - z)));
                }
            }
        }
    }
    
    signed main()
    {
        freopen("travel.in", "r", stdin);
        freopen("travel.out", "w", stdout);
        n = read();
        m = read();
        s = read();
        for(int i = 1; i <= m; ++i)
        {
            int x = read(), y = read();
            int z = read(), t = read();
            G.inc(x, y, z, t);
            G.inc(y, x, z, t);
        }
        for(int i = 1; i <= n; ++i)
        {
            c[i] = read();
            d[i] = read();
        }
        DJ();
        for(int i = 2; i <= n; ++i)
        {
            ll ans = 0x3f3f3f3f3f3f3f3f;
            for(int j = 0; j <= 5000; ++j)
                ans = min(ans, dis[i][j]);
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

    <后记>

    后面的题目就鸽了吧。。

    C题瞎搞有5分,D题我反手一个点分,明知道需要考虑重复色但是mode办法。

    正解什么的根本没听(懂)。

  • 相关阅读:
    py2与py3的字符编码的区别
    深浅拷贝大法
    列表、字典、元组、集合的内置方法
    数据类型的内置方法
    与while和for的爱恨情仇
    三种格式化输出以及运算符和if
    在outlook中发邮件判断邮件发送成功的方法
    修練營ASP.NET]淺談多層式架構 (Multi Tiers)
    软考编译原理小结
    0型文法、1型文法、2型文法、3型文法
  • 原文地址:https://www.cnblogs.com/yywxdgy/p/12882306.html
Copyright © 2020-2023  润新知