• CCPC 2016-2017, Finals


    A. HDU 5999 The Third Cup is Free

    简单模拟。

    B. HDU 6000 Wash

    n 件衣服, m 个洗衣机,k 个烘干机。每个洗衣机和烘干机需要不同的时间。问 n 件衣服洗完 + 烘干最小时间。

    看做两部:洗 + 烘干,用洗需要时间长的去配烘干需要时间短的,所有衣服取max。

    优先队列维护,取最小的,加上时长再放进去。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long LL;
    typedef pair<LL, int> pr;
    
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            int n, m, k;
            scanf("%d%d%d", &n, &m, &k);
    
            priority_queue<pr, vector<pr>, greater<pr> > q1, q2;
            LL x;
            for (int i = 1; i <= m; i++)
                scanf("%lld", &x), q1.push(pr(x, x));
            for (int i = 1; i <= k; i++)
                scanf("%lld", &x), q2.push(pr(x, x));
    
            vector<LL> a, b;
            LL ans = 0;
            for (int i = 1; i <= n; i++)
            {
                pr tmp = q1.top(); q1.pop();
                a.push_back(tmp.first); q1.push(pr(tmp.first + tmp.second, tmp.second));
            }
            int len = a.size();
            for (int i = 1; i <= n; i++)
            {
                pr tmp = q2.top(); q2.pop();
                q2.push(pr(tmp.first + tmp.second, tmp.second));
                ans = max(ans, a[len-i] + tmp.first);
            }
    
            printf("Case #%d: %lld
    ", ca, ans);
        }
    }
    

    C. HDU 6001 Mr.Panda and Survey

    容斥 + DFS

    D. HDU 6002 Game Leader

    优先队列贪心


    E. HDU 6003 Problem Buyer

    贪心。


    F. HDU 6004 Periodical Cicadas

    DP预处理 + exgcd


    G. HDU 6005 Pandaland

    给你一些边,求最小环。边数 <= 4000。

    枚举每条边,设其长度为 inf 后求两端点的最短路,最后再把答案加上原本的边长。

    最短路用堆优化的Dijkstra,若 dis + 边长 > ans直接停止,否则会TLE。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <set>
    using namespace std;
    typedef pair<int, int> pr;
    const int INF = 0x3f3f3f3f;
    const int maxn = 4000 + 100;
    int n;
    int sz = 0, tot;
    int v[2*maxn], last[2*maxn], nxt[2*maxn], lo[2*maxn];
    int dis[2*maxn], vis[2*maxn], ans;
    
    void build(int x,int y,int z)
    {
        sz++;
        v[sz] = y, nxt[sz] = last[x], last[x] = sz, lo[sz] = z;
        sz++;
        v[sz] = x, nxt[sz] = last[y], last[y] = sz, lo[sz] = z;
    }
    
    int Dijkstra(int s, int t, int extr)
    {
        for (int i = 1; i <= tot; i++)
            dis[i] = INF, vis[i] = 0;
        dis[s] = 0;
        priority_queue<pr, vector<pr>, greater<pr> > q;
        q.push(pr(0, s));
    
        while(!q.empty())
        {
            pr node = q.top(); q.pop();
            int x = node.second, length = node.first;
            if (length + extr > ans) break;
            if (vis[x]) continue;
            vis[x] = 1;
            for (int i = last[x]; i; i = nxt[i])
                if (dis[v[i]] > dis[x] + lo[i])
                {
                    dis[v[i]] = dis[x] + lo[i];
                    q.push(pr(dis[v[i]], v[i]));
                }
        }
        return dis[t];
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            tot = sz = 0;
            memset(last, 0, sizeof(last));
    
            map<pr, int> mp;
            scanf("%d", &n);
            int x1, x2, y1, y2, x;
            for (int i = 1; i <= n; i++)
            {
                scanf("%d%d%d%d%d", &x1,&y1,&x2,&y2,&x);
                if (mp[pr(x1, y1)] == 0) mp[pr(x1, y1)] = ++tot;
                if (mp[pr(x2, y2)] == 0) mp[pr(x2, y2)] = ++tot;
                build(mp[pr(x1, y1)], mp[pr(x2, y2)], x);
            }
    
            ans = INF;
            for (int i = 1; i <= sz; i += 2)
            {
                int x = v[i], y = v[i+1];
                int tmplen = lo[i];
                lo[i] = lo[i+1] = INF;
                ans = min(ans, Dijkstra(x, y, tmplen) + tmplen);
                lo[i] = lo[i+1] = tmplen;
            }
    
            if (ans >= INF) ans = 0;
    
            printf("Case #%d: %d
    ", ca, ans);
        }
    }
    

    H. HDU 6006 Engineer Assignment

    n 个工程,每个工程都有一些需求的领域。 m 个工程师,每个工程师有几个擅长的领域,且仅能被分配到一个项目。

    当且仅当一些工程师满足了项目的全部需求领域,这个项目才会被完成。问最多可以完成几个项目。

    n,m都很小,预处理出每个项目需要的工程师,状态压缩 + 背包。

    (x & j) == x时,证明 j 包含 x; j ^ x 就是 j 代表的集合减去 x 代表的集合。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <set>
    using namespace std;
    const int maxn = 10 + 10;
    
    vector<int> a[maxn], b[maxn];
    int e[maxn][1 << 11];
    int dp[maxn][1 << 11];
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            int n, m, k, x;
            scanf("%d%d", &n, &m);
    
            for (int i = 1; i <= n; i++) a[i].clear();
            for (int j = 1; j <= m; j++) b[j].clear();
            memset(e, 0, sizeof(0));
    
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", &k);
                for (int j = 1; j <= k; j++)
                    scanf("%d", &x), a[i].push_back(x);
            }
            for (int i = 1; i <= m; i++)
            {
                scanf("%d", &k);
                for (int j = 1; j <= k; j++)
                    scanf("%d", &x), b[i].push_back(x);
            }
    
            for (int i = 1; i <= n; i++)
            {
                set<int> st;
                for (int j = 0; j < a[i].size(); j++) st.insert(a[i][j]);
    
                for (int j = 1; j < (1<<m); j++)
                {
                    set<int> s2;
                    for (int k = 0; k < m; k++)
                        if (j & (1<<k)) for (int l = 0; l < b[k+1].size(); l++) s2.insert(b[k+1][l]);
    
                    set<int> :: iterator it;
                    int flag = 1;
                    for (it = st.begin(); it != st.end(); it++)
                        if (!s2.count(*it))
                        {
                            flag = 0;
                            break;
                        }
    
                    e[i][j] = flag;
                }
            }
    
            for (int i = 1; i <= n; i++)
                for (int j = 1; j < (1<<m); j++)
                {
                    dp[i][j] = dp[i-1][j];
                    for (int x = 1; x < (1<<m); x++)
                    if (e[i][x] && (x&j) == x)
                        dp[i][j] = max(dp[i][j], dp[i-1][j^x] + 1);
                }
    
            int ans = 0;
            for (int i = 1; i < (1<<m); i++)
                ans = max(ans, dp[n][i]);
    
            printf("Case #%d: %d
    ", ca, ans);
        }
    }
    

      

    I. HDU 6007 Mr. Panda and Crystal

    制造所有宝石都是可以用花费来衡量的。最短路跑出所有宝石的最小制作费用,然后完全背包就可以了。

    一种宝石可以更新花费,当且仅当有一种配方的总花费小于它的花费。可以用vector记录配方信息,然后再用一个vector记录每个宝石的配方下标。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const int maxn = 300 + 10;
    const int maxm = 400010;
    const int INF = 0x3f3f3f3f;
     
     
    int dis[maxn], weg[maxn];
    int vis[maxn];
    vector<int> a[maxn], aid[maxn], sum[maxn], tp[maxn];
    int v[2*maxm], last[2*maxm], nxt[2*maxm];
    int dp[maxm];
     
    int n, m, k, sz;
     
    void build(int x, int y)
    {
        sz++;
        v[sz] = y, nxt[sz] = last[x], last[x] = sz;
    }
     
    bool relax(int x, int y)
    {
        int siz = tp[y].size(), res = INF;
        for (int i = 0; i < siz; i++)
        {
            int to = tp[y][i], s = aid[to].size(), ans = 0, flag = 0;
            for (int j = 0; j < s; j++)
            {
                int ad = aid[to][j], sm = sum[to][j];
                if (dis[ad] == INF)
                {
                    flag = 1;
                    break;
                }
                ans += dis[ad] * sm;
            }
            if (flag == 0) res = min(res, ans);
        }
     
        if (dis[y] > res)
            return dis[y] = res, true;
        return false;
    }
     
     
    void SPFA()
    {
        queue<int> q;
        memset(vis, 0, sizeof(vis));
     
        for (int i = 1; i <= n; i++)
            if (dis[i] != INF) q.push(i), vis[i] = 1;
     
        while(!q.empty())
        {
            int x = q.front(); q.pop();
            for (int i = last[x]; i; i = nxt[i])
                if (relax(x, v[i]) && !vis[v[i]])
                    vis[v[i]] = 1, q.push(v[i]);
            vis[x] = 0;
        }
    }
     
     
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            sz = 0;
            memset(last, 0, sizeof(last));
     
            scanf("%d%d%d", &m, &n, &k);
            for (int i = 0; i < max(n, k); i++) aid[i].clear(), sum[i].clear(), tp[i].clear();
            //死在这里的clear了。不能只循环到n,因为k可能大于n。
     
            for (int i = 1; i <= n; i++)
            {
                int typ;
                scanf("%d", &typ);
                typ == 1 ? scanf("%d", &dis[i]):dis[i] = INF;
                scanf("%d", &weg[i]);
            }
     
            for (int i = 1; i <= k; i++)
            {
                int x, s, fr, d;
                scanf("%d%d", &x, &s);
                for (int j = 1; j <= s; j++)
                {
                    scanf("%d%d", &fr, &d);
                    build(fr, x);
                    aid[i].push_back(fr), sum[i].push_back(d);
                }
                tp[x].push_back(i);
            }
     
            SPFA();
     
            memset(dp, 0, sizeof(dp));
            for (int i = 1; i <= n; i++)
                for (int j = dis[i]; j <= m; j++)
                    dp[j] = max(dp[j], dp[j-dis[i]]+weg[i]);
     
            printf("Case #%d: %d
    ", ca, dp[m]);
        }
    }
    

      

      

    J. HDU 6008 Worried School

    题意复杂。

    set判重即可,分别求出两个名次。注意 region + final <= G-1 时是 "ADVANCED!" 。

    K. HDU 6009 Lazors

    模拟。


    L. HDU 6010 Daylight Saving Time

    模拟。只要处理出second Sunday in March first Sunday in November 是几号就可以了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    int run(int x)
    {
        if (x%4 == 0 && x%100 != 0) return 1;
        if (x%400 == 0) return 1;
        return 0;
    }
    
    int day(int y, int m, int d)
    {
        int sum = 0;
        for (int i = 2007; i < y; i++)
            sum += 365 + run(i);
    
        for (int i = 1; i < m; i++)
        {
            sum += mon[i];
            if (run[y] && i == 2) sum++;
        }
    
        sum += d;
        return sum%7;
    }
    
    int main()
    {
    
        int t;
        scanf("%d", &t);
    
        for (int ca = 1; ca <= t; ca++)
        {
            int y, m, d, h, mi, s;
            scanf("%d-%d-%d %d:%d:%d", &y,&m,&d,&h,&mi,&s);
            int pst = 0, pdt = 0;
    
            int times = 0, Nov = 1, Mar = 1;
            for (int i = 1; i <= 30; i++)
            {
                if (!day(y, 11, i)) times++;
                if (times == 2) { Nov = i; break; }
            }
            times = 0;
            for (int i = 1; i <= 30; i++)
            {
                if (!day(y, 11, i)) times++;
                if (times == 2) { Mar = i; break; }
            }
    
            printf("Case #%d: ", ca);
    
            if (m > 3 && m < 11) printf("PDT");
            if (m > 11 || m < 3) printf("PST");
            if (m == 3)
            {
                if (h >= 3) printf("PDT");
                    else if (h < 2) printf("PST");
                    else printf("Neither");
            }
            else if (m == 11)
            {
                if (h >= 2) printf("PST");
                    else if (h < 1) printf("PDT");
                    else printf("Both");
            }
            printf("
    ");
    
    
        }
    }
    

      

  • 相关阅读:
    微软免费人工智能课程
    如何定义,创建,启动一个线程
    什么是进程,什么是线程?
    Hashtable 数据遍历的几种方式
    action中result没有值
    <global-results>怎么用
    普通请求和ajax请求的区别
    result默认返回action中的所有数据,要想返回指定的数据怎么做呢
    ajax技术的应用?
    什么是国际化
  • 原文地址:https://www.cnblogs.com/ruthank/p/9737692.html
Copyright © 2020-2023  润新知