zoukankan      html  css  js  c++  java
  • JNday4-am

    T1

    对于T1,一直没什么思路,然而就放弃了,这道题真的挺简单的,
    我们可以到着想,那么就是将末状态变为0的操作数,这就不难了,
    然后类似于计数排序的思想搞一就相当于利用一个桶就可以了。
    操作时,将费0数不断减1,将0变为当前0的个数/2下取整。这貌似
    是一个非常优秀的贪心

    T2
    暴力加边,判断1和n的父亲是否相同,如果相同,answer ++,并且
    暴力再次将所有的点的父亲置为自己,这样竟然有80分,可见数据之水
    正解:
    暴力加边,每次进行bfs
    还可以单向并查集(第一次听说)

    T3
    贪心貌似0分,
    刚开始以为是贪心,每次只砍最小的奇数,如果没有奇数,那么放弃这一刀
    一定是最优的做法(4,4)(错的??)
    正解是dp
    f[i][j] 表示血量为i的兵,空了j刀,这里貌似并没有听懂
    GG,类似于一个背包问题,可以用一个栈来维护

    T1 集合

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <climits>
    #include <cstdlib>
    #include <cmath>
    #include <queue>
    #include <vector> 
    using namespace std; const int MAXN = 5e6 + 60, MX = 1e6; int N, a[MAXN], cnt[MAXN], res, lim; int main() { freopen("multiset.in", "r", stdin); freopen("multiset.out", "w", stdout); scanf("%d", &N); for (int i = 1; i <= N; ++i) { scanf("%d", &a[i]); lim = max(lim, a[i]); ++cnt[a[i]]; } int l = 0, z = cnt[0]; for (int i = 1; i <= lim; ++i) { ++res; z = (z + 1) / 2; z += cnt[i]; } for (; z > 1; z = (z + 1) / 2) ++res; printf("%d ", res); return 0; }

    T2道路分组

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    using namespace std;
    const int N=500010;
    typedef long long ll;
    
    int n, m;
    int vis[N], u[N], v[N];
    vector<int> vec[N];
    
    bool dfs(int u)
    {
        if (vis[u]) return false;
        if (u == n) return true;
        vis[u] = 1;
        bool ret = false;
        for (int i = 0; i < vec[u].size(); i++)
        {
            ret = dfs(vec[u][i]);
            if (ret) return true;
        }
        return false;
    }
            
    int read()
    {
        char ch = getchar();
        int x = 0;
        while (!isdigit(ch)) ch = getchar();
        while (isdigit(ch)) {x = x*10+(ch-'0');ch=getchar();}
        return x;
    }
    
    bool check(int sta, int las)
    {
        for (int i = sta; i <= las; i++)
            vec[u[i]].push_back(v[i]);
    
        bool ret = dfs(1);
    
        for (int i = sta; i <= las; i++)
        {
            vis[u[i]] = vis[v[i]] = 0;
            vec[u[i]].clear();
        }
        vis[1] = 0;
        return ret;
    }
        
    
    
    int main()
    {
        freopen("road.in","r",stdin);
        freopen("road.out","w",stdout);
        n = read(), m = read();
        for (int i = 0; i < m; i++)
        {
            //scanf("%d%d", &u[i], &v[i]);
            u[i] = read(); v[i] = read();
        }
        int now = 0, ans = 0;
        while (now < m)
        {
            int i;
            for (i = 1; i + now <= m; i <<= 1)
                if (check(now, now + i - 1)) break;
            i >>= 1; 
            int nowtmp = now + i;
            for (; i > 0; i >>= 1)
                if (nowtmp + i <= m && !check(now, nowtmp + i - 1))
                    nowtmp += i;
            ans++;
            now = nowtmp;
            
        }
        cout << ans << endl;
    }
                
                

    T3补刀

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    const int MAXN = 1000 + 10;
    int a[MAXN];
    int cnt[MAXN], sta[MAXN], c[MAXN];
    int f[MAXN][MAXN];
    
    int main()
    {
      freopen("cs.in", "r", stdin);
      freopen("cs.out", "w", stdout);
        int T;
        scanf("%d", &T);
        for (int num = 1; num <= T; ++num)
        {
            int N, maxn = 0;
            scanf("%d", &N);
            memset(cnt, 0, sizeof(cnt));
            memset(c, 0, sizeof(c));
            memset(f, 0, sizeof(f));
            for (int i = 1; i <= N; ++i)
            {
                scanf("%d", &a[i]); ++cnt[a[i]];
                maxn = max(maxn, a[i]);
            }
            int top = 0;
            for (int i = 1; i <= maxn; ++i)
                if (cnt[i] == 0) sta[++top] = i; else
                {
                    while (cnt[i] > 1 && top > 0) {c[sta[top--]] = i; --cnt[i];}
                    c[i] = i;
                }
            
            int ans = 0;
            for (int i = 1; i <= maxn; ++i)
                for (int j = 0; j <= i; ++j)
                {
                    if (j > 0) f[i][j] = f[i - 1][j - 1];
                    if (c[i] != 0 && j + c[i] - i < i)
                        f[i][j] = max(f[i][j], f[i - 1][j + c[i] - i] + 1);
                    ans = max(ans, f[i][j]);
                }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    Google I/O 官方应用中的动效设计
    浪院长 | spark streaming的使用心得
    Kubernetes 1.12公布:Kubelet TLS Bootstrap与Azure虚拟机规模集(VMSS)迎来通用版本号
    安卓自己定义View进阶-Path基本操作
    2014编程之美初赛第二场
    2015年,即将结束
    查看JVM运行时参数
    使用ThreadPoolExecutor线程池实现并发操作并返回结果
    mysql数据库将查询的多条结果的某些字段合并为一个字段处理
    mysql数据库使用mybatis新增操作返回自增主键的值
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7763889.html
Copyright © 2011-2022 走看看