• 2020杭电多校第四场


    1002.Blow up the Enemy

    先把最优的武器选出来,花最少时间能打死对面那种(不止一个)

    父亲想赢的话就只有赌中这些最优的武器概率为cnt/n,选出来了也只有1/2的概率赢

    最后我赢的概率就是父亲输的概率 ,1-cnt/2n

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    int n, a, b;
    int tmp, cnt, mt;
    inline void solve()
    {
        cin >> n;
        mt = 1e9;
        rep(i, 1, n)
        {
            cin >> a >> b;
            tmp = 100 / a;
            if (100 % a == 0)
                tmp--;
            tmp *= b;
            if (tmp == mt)
                cnt++;
            else if (tmp < mt)
            {
                cnt = 1;
                mt = tmp;
            }
        }
        cout << 1.0 * (2 * n - cnt) / (2 * n) << endl;
    }
    int main()
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int t = 1;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code

    1004.Deliver the Cake

    最短路问题,经过某些村庄必须停留换手。。

    直接上Dijkstra,考虑经过M的时候把他拆成l,r两个点。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    struct edges
    {
        int to, next, w;
    } e[400010];
    int id, head[100010];
    inline void add(int x, int y, int w)
    {
        e[++id].w = w;
        e[id].to = y;
        e[id].next = head[x];
        head[x] = id;
    }
    struct node
    {
        unsigned long long u, d, flag;
        bool operator<(const node &f) const { return d > f.d; }
    };
    priority_queue<node> q;
    
    unsigned long long n, m, s, v, x;
    char str[100010];
    int dir[100010], vis[100010][3];
    unsigned long long dis[100010][3];
    
    inline void solve()
    {
        cin >> n >> m >> s >> v >> x;
        cin >> str;
        rep(i, 0, n - 1) if (str[i] == 'M')
            dir[i + 1] = 0;
        else if (str[i] == 'L') dir[i + 1] = 1;
        else if (str[i] == 'R') dir[i + 1] = 2;
    
        id = 0;
        memset(e, 0, sizeof(e));
        rep(i, 1, n)
        {
            dis[i][1] = dis[i][2] = 1e16;
            head[i] = vis[i][1] = vis[i][2] = 0;
        }
        int a, b, w;
        rep(i, 1, m)
        {
            cin >> a >> b >> w;
            add(a, b, w);
            add(b, a, w);
        }
        if (dir[s])
        {
            q.push((node){s, 0, dir[s]});
            dis[s][dir[s]] = 0;
        }
        else
        {
            q.push((node){s, 0, 1});
            q.push((node){s, 0, 2});
            dis[s][1] = dis[s][2] = 0;
        }
        while (!q.empty())
        {
            s = q.top().u;
            int flag = q.top().flag, flag2;
            q.pop();
            if (vis[s][flag])
                continue;
            vis[s][flag] = 1;
            for (int i = head[s]; i; i = e[i].next)
            {
                ll tmp = dis[s][flag] + e[i].w;
                flag2 = dir[e[i].to];
                if (flag2)
                {
                    if (flag != flag2)
                        tmp += x;
                    if (!vis[e[i].to][flag2] && dis[e[i].to][flag2] > tmp)
                    {
                        dis[e[i].to][flag2] = tmp;
                        q.push((node){e[i].to, dis[e[i].to][flag2], flag2});
                    }
                }
                else
                {
                    if (!vis[e[i].to][flag] && dis[e[i].to][flag] > tmp)
                    {
                        dis[e[i].to][flag] = tmp;
                        q.push((node){e[i].to, dis[e[i].to][flag], flag});
                    }
                    if (!vis[e[i].to][3 - flag] && dis[e[i].to][3 - flag] > tmp + x)
                    {
                        dis[e[i].to][3 - flag] = tmp + x;
                        q.push((node){e[i].to, dis[e[i].to][3 - flag], 3 - flag});
                    }
                }
            }
        }
        if (dir[v])
            cout << dis[v][dir[v]] << endl;
        else
            cout << min(dis[v][1], dis[v][2]) << endl;
    }
    int main()
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int t = 1;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code

    1005.Equal Sentences

    每个单词出现的位置不能差超过1的长度,这就限制了只能相邻的两个单词交换。

    相同的单词不能交换,那就记录下当前位置种类数。

    dp[i][0]表示与上一个位置不交换,dp[i][0] = dp[i-1][0] + dp[i-1][1]

    dp[i][1]表示与上一个位置交换,如果当前单词与上一个相等,则dp[i][1]=0,不相等dp[i][1] = dp[i-1][0]

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    int mod = 1e9 + 7;
    int n;
    char a[100010][15];
    int vis[100010], dp[100010][2];
    inline void solve()
    {
        memset(a, 0, sizeof(a));
        cin >> n;
        rep(i, 1, n)
        {
            scanf("%s", a[i]);
            dp[i][0] = dp[i][1] = 0;
            vis[i] = strcmp(a[i], a[i - 1]) == 0;
        }
        dp[1][0] = 1;
        rep(i, 2, n)
        {
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
            dp[i][1] = vis[i] ? 0 : dp[i - 1][0];
        }
        cout << (dp[n][0] + dp[n][1]) % mod << endl;
    }
    int main()
    {
        // ios_base::sync_with_stdio(0);
        // cin.tie(0);
        // cout.tie(0);
    
        int t = 1;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code

    1007.Go Running

    每个人只能往某一个方向跑,告诉你 t 时刻在 x 位置有人,问最少有多少个人。

    由于只能往一个方向跑,那么x和t和或者差相等的一些点可以分为一个人,

    把(t,x)点对画在坐标轴上,一条斜率为1或者-1的直线就表示一个人,

    坐标轴旋转一下,就简化成画多少条平行于坐标轴的直线能将平面上的点覆盖,

    这就简化成了二分图的经典模型,将每个点横坐标向纵坐标连边,求最大匹配。

    匈牙利算法复杂度O(n2),这里用网络流dinic O(n√n)的方式解决

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    struct edge
    {
        int to, next, w;
    } e[600100];
    int id, head[200100];
    void add(int x, int y)
    {
        e[++id] = (edge){y, head[x], 1};
        head[x] = id;
        e[++id] = (edge){x, head[y], 0};
        head[y] = id;
    }
    
    int n, a[100010], b[100010], mia[100010], mib[100010];
    int s, v, ans;
    
    int dis[200100];
    queue<int> q;
    bool bfs()
    {
        rep(i, 1, v) dis[i] = -1;
        dis[s] = 0;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = head[u]; i; i = e[i].next)
                if (dis[e[i].to] == -1 && e[i].w > 0)
                {
                    dis[e[i].to] = dis[u] + 1;
                    q.push(e[i].to);
                }
        }
        return dis[v] != -1;
    }
    int dfs(int u, int limit)
    {
        if (u == v)
            return limit;
        int flow = 0, tmp = 0;
        for (int i = head[u]; i; i = e[i].next)
        {
            if (dis[e[i].to] == dis[u] + 1 && e[i].w > 0)
            {
                tmp = dfs(e[i].to, min(limit, e[i].w));
                if (!tmp)
                    continue;
                limit -= tmp;
                flow += tmp;
                e[i].w -= tmp;
                e[i ^ 1].w += tmp;
                if (!limit)
                    break;
            }
        }
        return flow;
    }
    inline void solve()
    {
        cin >> n;
        id = 1;
        memset(head, 0, sizeof(head));
        memset(e, 0, sizeof(e));
        int aa, bb;
        rep(i, 1, n)
        {
            cin >> aa >> bb;
            mia[i] = a[i] = bb + aa;
            mib[i] = b[i] = bb - aa;
        }
        sort(mia + 1, mia + n + 1);
        sort(mib + 1, mib + n + 1);
        int na = unique(mia + 1, mia + n + 1) - mia - 1;
        int nb = unique(mib + 1, mib + n + 1) - mib - 1;
        s = na + nb + 1;
        v = s + 1;
        map<int, int> mpa, mpb;
        rep(i, 1, na)
        {
            mpa[mia[i]] = i;
            add(s, i);
        }
        rep(i, 1, nb)
        {
            mpb[mib[i]] = i + na;
            add(i + na, v);
        }
        rep(i, 1, n) add(mpa[a[i]], mpb[b[i]]);
    
        ans = 0;
        while (bfs())
            ans += dfs(s, 1e9);
        cout << ans << endl;
    }
    int main()
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int t = 1;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code

    1011.Kindergarten Physics

    签到题!算得正嗨,队友说直接输出(d-1).9999999

    题解也是直接输出d

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    int a, b, c, d;
    inline void solve()
    {
        cin >> a >> b >> c >> d;
        cout << c - 1 << ".999999999
    ";
    }
    int main()
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int t = 1;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code

    1012.Last Problem

    构造题,要在(x,y)位置填n,必须要在四周填n-1,n-2,n-3,n-4。

    暴搜,让n-1,n-4在两侧,n-2,n-3在两侧可以减少重复填数的次数。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define rep(i, a, b) for (register int i = a; i <= b; i++)
    
    typedef pair<int, int> pii;
    #define mk(x, y) make_pair(x, y)
    int n;
    map<pii, int> mp;
    
    inline void dfs(int x, int y, int k)
    {
        if (k > 1 && mp[mk(x + 1, y)] != k - 1)
            dfs(x + 1, y, k - 1);
        if (k > 2 && mp[mk(x, y + 1)] != k - 2)
            dfs(x, y + 1, k - 2);
        if (k > 3 && mp[mk(x, y - 1)] != k - 3)
            dfs(x, y - 1, k - 3);
        if (k > 4 && mp[mk(x - 1, y)] != k - 4)
            dfs(x - 1, y, k - 4);
        mp[mk(x, y)] = k;
        cout << x << " " << y << " " << k << endl;
    }
    
    inline void solve()
    {
        cin >> n;
        dfs(0, 0, n);
    }
    int main()
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    
        int t = 1;
        // cin >> t;
        while (t--)
        {
            solve();
        }
    }
    View Code
  • 相关阅读:
    第十一周课程总结
    第十周课程总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告(六)
    第七周课程总结&实验报告(五)
    第六周课程总结&试验报告(四)
    课程总结
    第十四周课程总结&实验报告(简单记事本的实现)
    第十三周
    第十二周学习总结
  • 原文地址:https://www.cnblogs.com/likunhong/p/13406072.html
Copyright © 2020-2023  润新知