• 牛客练习赛20


    A.礼物

    题意:有n种1元礼物和m种2元礼物 你有k元你能搭配出多少种组合

    题解:他们都写的背包 发现我不会

       就枚举买几个1元的礼物 剩下部分买2元的 然后用组合数学搞搞

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    ll f[2005][2005];
    void fun(ll mod)
    {
        for(int i = 0; i <= 2000; i++) f[i][0] = 1LL;
        for(int i = 1; i <= 2000; i++)
        {
            for(int j = 1; j <= i; j++)
                f[i][j] = (f[i - 1][j - 1] + f[i - 1][j]) % mod;
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            ll n, m, k, p;
            cin>>n>>m>>k>>p;
            fun(p);
    
            ll ans = f[k + n - 1][k];
            if(m != 0)
            {
                for(int i = 1; i < k; i++)
                {
                    if((k - i) & 1) continue;
                    int j = (k - i) >> 1;
                    ans = (ans + f[i + n - 1][i] * f[j + m - 1][j] % p) % p;
                }
            }
            if(k % 2 == 0) ans = (ans + f[k / 2 + m - 1][k / 2]) % p;
    
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

    B.麻婆豆腐

    题意:给出n枚硬币正面朝上的概率 求有多少子集使得硬币正面朝上次数为奇数的概率等于偶数

    题解:发现对于一个集合 如果有正面朝上概率为0.5的硬币 那么其余硬币随便怎么搞都满足

       比如我们要求正面朝上的概率为奇数的个数 假设除了0.5的硬币其他硬币为奇数的概率为p 为偶数的概率为1-p

       那么p为奇数 = p*0.5 + (1 - p)*0.5 所以含有0.5正面朝上概率硬币的子集一定满足

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int cnt = 0;
            int n; cin>>n;
            double x;
            for(int i = 1; i <= n; i++)
            {
                cin>>x;
                if(fabs(x - 0.5) < 1e-7) cnt++;
            }
            ll ans = ((1LL << (ll)cnt) - 1LL) * (1LL << (ll)(n - cnt));
            printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

    C.寻宝

    题意:n个点 每个点能到达另外一个点 选择一个点作为起点 能最多经历多少不同的点

    题解:n个点n条边 那么这一定是由一些带环树组成的 dfs找出每一块然后记忆化更新答案

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    using namespace std;
    const int maxn = (1 << 24) + 5;
    typedef long long ll;
    
    vector<int> g;
    int to[maxn];
    int dp[maxn];
    int vis[maxn];
    
    int st;
    void dfs(int x)
    {
        dp[x] = 1;
        vis[x] = -1;
        int v = to[x];
        if(v == x)
        {
            vis[x] = 1;
            return;
        }
    
        if(vis[v] == 1) dp[x] += dp[v];
        else if(vis[v] == 0)
        {
            dfs(v);
            if(st == -1) dp[x] += dp[v];
            else if(x == st)
            {
                g.push_back(x);
                int tmp = g.size();
                for(int i = 0; i < g.size(); i++) dp[g[i]] = tmp;
                st = -1;
                g.clear();
            }
            else g.push_back(x);
        }
        else if(vis[v] == -1) st = v, g.push_back(x);
        vis[x] = 1;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            st = -1;
            ll a, b, c, n;
            cin>>a>>b>>c>>n;
    
            for(ll i = 0; i < n; i++)
            {
                dp[i] = 0; vis[i] = 0;
                to[i] = (a * i * i  + b * i + c) % n;
                to[i] = (to[i] + n) % n;
            }
            int ans = 0;
            for(int i = 0; i < n; i++)
            {
                if(!vis[i]) dfs(i);
                ans = max(ans, dp[i]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    D.最短路2

    题意:在网格图上给两个点和一条直线 能从网格和直线上走 求最短路

    题解:以两个点做出一个正方形 然后这条直线最多会和这个正方形有两个交点 以这些点建图跑最短路就好了

       直线上两个点之间的距离是普通距离 其他则是曼哈顿距离

    #include <bits/stdc++.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    double x1, yy, x2, y2, a, b, c;
    
    struct node
    {
        double x, y;
        int ty;
    }E[25];
    
    struct no1
    {
        int to;
        double val;
    };
    vector<no1> g[35];
    
    double dis[35];
    int vis[25];
    queue<int> que;
    
    void spfa()
    {
        for(int i = 1; i <= 10; i++) dis[i] = 1000000005;
        memset(vis, 0, sizeof(vis));
        dis[1] = 0; vis[1] = 1;
        while(!que.empty()) que.pop();
        que.push(1);
    
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            vis[u] = 0;
            for(int i = 0; i < g[u].size(); i++)
            {
                if(dis[u] + g[u][i].val < dis[g[u][i].to])
                {
                    dis[g[u][i].to] = dis[u] + g[u][i].val;
                    if(!vis[g[u][i].to])
                    {
                        vis[g[u][i].to] = 1;
                        que.push(g[u][i].to);
                    }
                }
            }
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            for(int i = 1; i <= 20; i++) g[i].clear();
            scanf("%lf %lf %lf %lf %lf %lf %lf", &x1, &yy, &x2, &y2, &a, &b, &c);
            double xx = min(x1, x2);
            double xd = max(x1, x2);
            double yx = min(yy, y2);
            double yd = max(yy, y2);
            E[1].x = x1; E[1].y = yy; E[1].ty = 0;
            E[2].x = x2; E[2].y = y2; E[2].ty = 0;
            E[3].x = x1; E[3].y = y2; E[3].ty = 0;
            E[4].x = x2; E[4].y = yy; E[4].ty = 0;
            int cnt = 4;
    
    
            if(fabs(a) > 1e-9)
            {
                double x3 = (c - b * yy) / a;
                if(x3 >= xx && x3 <= xd)
                {
                    cnt++;
                    E[cnt].x = x3; E[cnt].y = yy; E[cnt].ty = 1;
                }
    
                double x4 = (c - b * y2) / a;
                if(x4 >= xx && x4 <= xd)
                {
                    cnt++;
                    E[cnt].x = x4; E[cnt].y = y2; E[cnt].ty = 1;
                }
            }
    
            if(fabs(b) > 1e-9)
            {
                double y3 = (c - a * x1) / b;
                if(y3 >= yx && y3 <= yd)
                {
                    cnt++;
                    E[cnt].x = x1; E[cnt].y = y3; E[cnt].ty = 1;
                }
    
                double y4 = (c - a * x2) / b;
                if(y4 >= yx && y4 <= yd)
                {
                    cnt++;
                    E[cnt].x = x2; E[cnt].y = y4; E[cnt].ty = 1;
                }
            }
    
            for(int i = 1; i <= cnt; i++)
            {
                for(int j = 1; j <= cnt; j++)
                {
                    if(i == j) continue;
                    if(E[i].ty + E[j].ty < 2)
                    {
                        no1 p; p.to = j; p.val = fabs(E[i].x - E[j].x) + fabs(E[i].y - E[j].y);
                        g[i].push_back(p);
                    }
                    else if(E[i].ty + E[j].ty == 2)
                    {
                        no1 p; p.to = j; p.val = sqrt((E[i].x - E[j].x) * (E[i].x - E[j].x) + (E[i].y - E[j].y) * (E[i].y - E[j].y));
                        g[i].push_back(p);
                    }
                }
            }
            spfa();
            printf("%.3lf
    ", dis[2]);
        }
        return 0;
    }
    View Code

    E.托米历险记 签到

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    int sum[5];
    
    int main()
    {
        bool f = true;
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            int x; scanf("%d", &x);
            x /= 25;
            if(x == 1) sum[1]++;
            else if(x == 2)
            {
                if(!sum[1]) f = false;
                sum[1]--;
                sum[2]++;
            }
            else if(x == 4)
            {
                if(sum[1] && sum[2])
                {
                    sum[1]--;
                    sum[2]--;
                }
                else if(!sum[2])
                {
                    sum[1] -= 3;
                    if(sum[1] < 0) f = false;
                }
                else if(!sum[1]) f = false;
            }
        }
        if(f) puts("YES");
        else puts("NO");
    
        return 0;
    }
    View Code

    F.填数字 随便贪心

    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    int a[15];
    
    int main()
    {
        int n; cin>>n;
    
        int zd = 10000000; int mark = -1;
        for(int i = 1; i <= 9; i++)
        {
            cin>>a[i];
            if(a[i] <= zd)
            {
                zd = a[i];
                mark = i;
            }
        }
        zd = n / a[mark];
    
        if(zd == 0) puts("-1");
        else
        {
            int x = zd * a[mark];
            int res = n - x;
            int cnt = 0;
    
            for(int i = 9; i > mark; i--)
            {
                while(res >= a[i] - a[mark])
                {
                    res -= a[i] - a[mark];
                    cnt++;
                    printf("%d", i);
                }
            }
            for(int i = cnt + 1; i <= zd; i++) printf("%d", mark);
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    20155339 Exp9 Web安全基础
    20155339 Exp8 Web基础
    20155339 Exp7 网络欺诈防范
    20155339 Exp6 信息搜集与漏洞扫描
    20155339 Exp5 MSF基础应用
    20155339 Exp4 恶意代码分析
    20155339 Exp3 免杀原理与实践
    20155339平措卓玛 Exp2 后门原理与实践
    20155339平措卓玛 Exp1 PC平台逆向破解(5)M
    20155339 第16周课堂实践加分作业
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9191700.html
Copyright © 2020-2023  润新知