• 6.2三道模拟


    真的是太菜了...

    题也不会做,策略也失误,对T2过于自信认为自己能A,结果T3看都没看...最后只拿100分

    这个题应该拿250+的啊...

    T1 https://www.luogu.org/problemnew/show/P4071

    预处理组合数和错排直接回答就行

    30mins(考试时)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<ctime>
    #include<vector>
    #include<map>
    #include<queue>
    using namespace std;
    #define ll long long
    inline ll read()
    {
        ll ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch >'9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int mod = 1e9 + 7;
    const int maxn = 1e6 + 10;
    ll power(ll a,ll b)
    {
        ll ans = 1,res = a;
        while(b)
        {
            if(b & 1) (ans *= res) %= mod;
            (res *= res) %= mod;
            b >>= 1;
        }
        return ans;
    }
    ll fac[maxn],inv[maxn];
    ll n,m;
    ll ans;
    ll cal(ll n,ll m)
    {
        return fac[n] * inv[m] % mod * inv[n - m] % mod;
    }
    ll f[maxn];
    int main()
    {
        ll t = read();
        inv[0] = fac[0] = 1;
        for(int i = 1;i <= maxn - 10;i++)
        {
            fac[i] = fac[i - 1] * i % mod;
            inv[i] = power(fac[i],mod - 2);
        }
        f[1] = 0,f[2] = f[0] = 1;
        for(int i = 3;i <= maxn - 10;i++)
            f[i] = (i - 1) * (f[i - 1] + f[i - 2]) % mod;
        while(t--)
        {
            n = read(),m = read();
            printf("%lld
    ",cal(n,m) * f[n - m] % mod);
        }
    }
    View Code

    T2 https://www.luogu.org/problemnew/show/P2446

    考虑到可以让无数个机器人同时出发,那么一个节点可以有两个dis值

    分别是图上的最短路距离和实际到达的最早时间

    然后你可以边dij边处理第二个值,当一个节点的所有保护城市都被访问过以后就把这个点塞进堆

    爆零是因为更新dis的时候,想当然的按照传统dij用数组里的值更新,然而这道题应该拿实际时间更新,不然一边dij一边处理就失去意义了,还不如用拓扑排序

    2.5h(考试 + 订正)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    #define O(x) cout << #x << "  " << x << endl;
    #define pii pair<ll,int> 
    #define mp make_pair
    #define B cout << "breakpoint" << endl;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 3005;
    const int maxm = 70005;
    const ll inf = 99999999999;
    int n,m;
    struct egde
    {
        int to,next;
        ll cost;
    }e[maxm];
    int fir[maxn],alloc;
    void adde(int u,int v,ll w)
    {
        e[++alloc].next = fir[u];
        fir[u] = alloc;
        e[alloc].to = v;
        e[alloc].cost = w;
    }
    vector<int> l[maxn];
    int cnt[maxn];
    
    ll dis[maxn];
    ll res[maxn];
    bool vis[maxn];
    void dij()
    {
        for(int i = 1;i <= n;i++) dis[i] = inf;
        priority_queue<pii,vector<pii>,greater<pii> > p;
        p.push(mp(0,1));
        dis[1] = 0;
        while(p.size())
        {
            pii t = p.top();
            p.pop();
            int u = t.second;
            //O(u);
            ll dist = t.first;
            if(vis[u]) continue;
            vis[u] = 1;
            for(int i = fir[u];i;i = e[i].next)
            {
                int v = e[i].to;
                ll w = e[i].cost;
                if(dis[v] > dist + w)
                {
                    dis[v] = dist + w;
                    if(cnt[v] == 0) p.push(mp(max(dis[v],res[v]),v));
                }
            }
            for(int i = 0;i < l[u].size();i++)
            {
                int v = l[u][i];
                //O(v);
                cnt[v]--;
                res[v] = max(res[v],dist);
                if(cnt[v] == 0) p.push(mp(max(dis[v],res[v]),v));
            }
        }
    }
    int main()
    {
        //freopen("landcraft.in","r",stdin);
        //freopen("landcraft.out","w",stdout);
        n = read(),m = read();
        for(int i = 1;i <= m;i++)
        {
            int u = read(),v = read(),w;
            scanf("%lld",&w);
            if(u == v) continue;
            adde(u,v,w);
        }
        for(int i = 1;i <= n;i++)
        {
            cnt[i] = read();
            for(int j = 1;j <= cnt[i];j++)
            {
                int v = read();
                l[v].push_back(i);
            }
        }
        dij();
        printf("%lld",max(dis[n],res[n]));
    }
    View Code

    T3 https://www.luogu.org/problemnew/show/P3745

    这么直白的题考试的时候应该多放时间的...确实是被T2扰乱视听了

    不会三分,用个很直白的枚举做法

    枚举最晚结束时间,你就可以算出在这个时间结束的时候的花费

    O(nlogn),虽然比别的做法多个log,但是代码难度几乎是没有的,而且非常易懂,重要的是可以过

    然后不要忘了,学生的不满意度应该是被加进花费的(根据定义)

    1.0h(订正)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<ctime>
    #include<vector>
    #include<map>
    #include<queue>
    using namespace std;
    typedef int mainint;
    #define int unsigned long long
    #define O(x) cout << #x << " " << x << endl;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch >'9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e5 + 5;
    int A,B,C;
    int n,m;
    int t[maxn],sumt[maxn];//希望时间 
    int b[maxn],sumb[maxn];//实际时间 
    int ans = LONG_LONG_MAX;
    mainint main()
    {
        A = read(),B = read(),C = read();
        n = read(),m = read();
        for(int i = 1;i <= n;i++) t[i] = read();
        for(int i = 1;i <= m;i++) b[i] = read();
        sort(t + 1,t + 1 + n);
        sort(b + 1,b + 1 + m);
        for(int i = 1;i <= n;i++)  sumt[i] = sumt[i - 1] + t[i];
        for(int i = 1;i <= m;i++)  sumb[i] = sumb[i - 1] + b[i];
        for(int i = min(t[1],b[1]);i <= max(t[n],b[m]);i++)
        {
            int tp = 0;
            int p1 = lower_bound(b + 1,b + 1 + m,i) - b;//b[p1] <= i的最大b[p1]
            while(b[p1] > i) p1--;
            int tp1 = p1 * i - sumb[p1],tp2 = sumb[m] - sumb[p1] - (m - p1) * i;//tp1:可以调的时间,tp2:实际需要调的时间 
            //O(i); O(tp1); O(tp2);
            if(A < B)
            {
                if(tp1 > tp2) tp += A * tp2;
                else tp += A * tp1 + B * (tp2 - tp1);
            }
            else tp += B * tp2;
            int tot = lower_bound(t + 1,t + 1 + n,i) - t;
            while(t[tot] > i) tot--;//t[tot] <= i 的最大t[tot]
            tp = tp + (tot * i - sumt[tot]) * C;
            ans = min(ans,tp);
        }
        cout << ans;
    }
            
        
    View Code
  • 相关阅读:
    linux学习 建立静态库,动态库,写简单的makefile
    C++中顶层const和底层const
    BDB (Berkeley DB)数据库简单介绍(转载)
    Java中Map的使用
    Spring MVC 3 深入总结
    nvl,空时的推断和取值
    java堆栈 (转)
    mybatis--面向接口编程
    HDU 4888
    socket编程——一个简单的样例
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/10983694.html
Copyright © 2020-2023  润新知