zoukankan      html  css  js  c++  java
  • 福州大学第十一届程序设计竞赛

    福州大学第十一届程序设计竞赛
    Contest Finished!
    Tag Pro.ID Problem Title Ratio(AC/Submit)
    1 大王叫我来巡山呐 80.31%(261/325)
    2 防守阵地 I 23.48%(193/822)
    3 shadow 13.23%(97/733)
    4 花生的序列 12.07%(21/174)
    5 防守阵地 II 14.98%(68/454)
      6 巡了南山我巡北山 0.00%(0/45)
    7 Nostop 20.79%(21/101)
      8 卷福的难题 10.00%(1/10)
            

                   本来打算当作组队赛来做的,结果队友有足球赛,另一个有党校。。仅仅剩下我一个人单挑了。 @.@   还好不是非常难,不然就被虐翻了。

    。总体来说题目比較简单,应该本来就是作为个人赛准备的。。

                   A题签到题

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    const int maxn = 5;
    const int INF = 0x3f3f3f3f;
    
    int main()
    {
        int n;
        while(scanf("%d", &n) != EOF)
        {
            int ans = n / 7 * 2;
            if(n % 7 == 6) ans ++;
            printf("%d
    ", ans);
        }
    }
    

                      B题观察式子转移,就能够非常easy发现端倪了。。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    const int maxn = 1001000;
    const int INF = 0x3f3f3f3f;
    
    int a[maxn];
    
    int main()
    {
        int n, m;
        while(scanf("%d%d", &n, &m) != EOF)
        {
            int ans = 0, tot = 0, sum = 0;
            for(int i = 1; i <= m; i ++)
            {
                scanf("%d", &a[i]);
                sum += a[i];
                tot += i*a[i];
            }
            ans = tot;
            for(int i = m + 1; i <= n; i ++)
            {
                scanf("%d", &a[i]);
                tot -= sum;
                sum -= a[i - m];
                sum += a[i];
                tot += a[i] * m;
                ans = max(ans, tot);
            }
            printf("%d
    ", ans);
        }
    }
    
                 C题是比較简单的树dp吧,仅仅须要看孩子和本身有没有士兵,有的话当前点肯定会被消灭。

    OJ比較奇特,递归会爆栈,用vector会超时。。不幸的是两种情况我都遇到了。。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define MP make_pair
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    const int maxn = 100100;
    const int INF = 0x3f3f3f3f;
    
    int arm[maxn];
    bool hav[maxn];
    
    struct Edge
    {
        int u, v;
    }E[maxn*2];
    
    int fir[maxn], nxt[maxn*2], tot = 0;
    
    LL d[maxn];
    
    void AddEdge(int u, int v)
    {
        E[tot].u = u, E[tot].v = v;
        nxt[tot] = fir[u], fir[u] = tot ++;
    }
    
    LL dfs()
    {
        stack<pair<int, int> > S;
        CLR(d, 0);
        S.push(MP(1, 0));
        int cnt = 0;
        while(!S.empty())
        {
            int u = S.top().first, fa = S.top().second;
            if(fir[u] == -1)
            {
                if(hav[u]) hav[fa] = 1, d[fa] += d[u] + arm[u];
                S.pop();
            }
            else
            {
                int v = E[fir[u]].v;
                fir[u] = nxt[fir[u]];
                if(v == fa) continue;
                S.push(MP(v, u));
            }
        }
        return d[1];
    }
    
    int main()
    {
        int n, k;
        while(scanf("%d%d", &n, &k) != EOF)
        {
            for(int i = 1; i <= n; i ++)
            {
                scanf("%d", &arm[i]);
            }
            CLR(hav, 0);CLR(fir, -1); tot = 0;
            for(int i = 0; i < k; i ++)
            {
                int u; scanf("%d", &u);
                hav[u] = 1;
            }
            for(int i = 1; i < n; i ++)
            {
                int u, v;
                scanf("%d%d", &u, &v);
                AddEdge(u, v);
                AddEdge(v, u);
            }
    
            printf("%lld
    ", dfs());
        }
    }
    
                D题算是一道dp吧。dp[i][j]。表示到第i为为止。有j个属于第一个串,由于串的特殊性(WBWBWB)。所以非常easy推断当前位置的字母满足的情况。比方当前j为奇数。那么j后面肯定仅仅能接B。

    。。就这样。。。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    const int maxn = 10100;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    
    char ch[maxn];
    int dp[2][3300];
    
    int main()
    {
        int T, n;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%d%s", &n, ch);
            CLR(dp, 0);
            dp[0][0] = 1;
            for(int i = 0, j = 1; i < n * 2; i ++, j ++)
            {
                CLR(dp[j&1], 0);
                if(ch[i] == 'B')
                {
                    for(int k = 0; k <= n; k ++)
                    {
                        if(k&1) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD;
                        if((i-k)&1) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD;
                    }
                }
                else
                {
                    for(int k = 0; k <= n; k ++)
                    {
                        if((k&1) == 0) dp[j&1][k+1] = (dp[j&1][k+1] + dp[i&1][k]) % MOD;
                        if(((i-k)&1) == 0) dp[j&1][k] = (dp[j&1][k] + dp[i&1][k]) % MOD;
                    }
                }
            }
            printf("%d
    ", dp[0][n]);
        }
    }
    
                   E裸线段树区间更新。区间查询。仅仅要你不想那么多,就能够直接A掉。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define CLR(a, b) memset(a, b, sizeof(a))
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    using namespace std;
    
    const int maxn = 100100;
    const int INF = 0x3f3f3f3f;
    
    int add[maxn<<2];
    int sum[maxn<<2];
    
    void PushUp(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void PushDown(int rt,int m)
    {
        if (add[rt])
        {
            add[rt<<1] += add[rt];
            add[rt<<1|1] += add[rt];
            sum[rt<<1] += add[rt] * (m - (m >> 1));
            sum[rt<<1|1] += add[rt] * (m >> 1);
            add[rt] = 0;
        }
    }
    void build(int l,int r,int rt)
    {
        add[rt] = 0;
        if (l == r)
        {
            scanf("%d",&sum[rt]);
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void update(int L,int R,int c,int l,int r,int rt)
    {
        if (L <= l && r <= R)
        {
            add[rt] += c;
            sum[rt] += c * (r - l + 1);
            return ;
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        if (L <= m) update(L , R , c , lson);
        if (m < R) update(L , R , c , rson);
        PushUp(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if (L <= l && r <= R)
        {
            return sum[rt];
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        LL ret = 0;
        if (L <= m) ret += query(L , R , lson);
        if (m < R) ret += query(L , R , rson);
        return ret;
    }
    int main()
    {
        int n, m, q;
        while(scanf("%d%d%d", &n, &m, &q) != EOF)
        {
            build(1, n, 1);
            for(int i = 0; i < q; i ++)
            {
                int x; scanf("%d", &x);
                printf("%d
    ", query(x, x + m - 1, 1, n, 1));
                update(x, x + m - 1, -1, 1, n, 1);
            }
        }
    }
    
    

                    F应该是搜索吧。

    。。感觉无从下手,罪过。。

    大致思路应该是推断是否是子串。然后在进行加字符,copy操作吧。。

    我猜的。。

                    G题这种题第一次见到。感觉自己YY出来还是非常高兴的!就是用矩阵来表示走K步之后的各个点对到达所须要的最小花费。

    这种话,我们就能够用初始矩阵(表示的是1步到达的情况)不断更新,来获得走2步,走3步的到达情况。。这种话思路就非常明白了。由于题目数据比較大。我们直接用高速幂更新就能够了。(应该非常easy想到这些更新是满足结合率的吧)。我还是认为看代码清楚些。。这个OJ非常个性,用lld。wa了无数次,改成cin,cout才过。。

    =.=!!

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define LL long long
    #define MP make_pair
    #define CLR(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 55;
    const LL INF = 1ll << 60;
    
    struct Matrix
    {
        LL m[maxn][maxn];
    }sol, pre;
    
    int n;
    
    Matrix Add(Matrix a, Matrix b)
    {
        Matrix ret;
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= n; j ++)
            {
                ret.m[i][j] = INF;
                LL& tmp = ret.m[i][j];
                for(int k = 1; k <= n; k ++)
                {
                    tmp = min(tmp, a.m[i][k] + b.m[k][j]);
                }
            }
        }
        return ret;
    }
    
    Matrix Mul(Matrix a, int n)
    {
        Matrix ret;
        bool flag = false;
        while(n)
        {
            if(n & 1)
            {
                if(flag) ret = Add(ret, a);
                else ret = a;
                flag = true;
            }
            a = Add(a, a);
            n >>= 1;
        }
        return ret;
    }
    
    void pt(Matrix sol)
    {
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= n; j ++)
                printf("%lld ", sol.m[i][j]);
                puts("");
        }
    }
    
    int main()
    {
        int h, k, T;
        scanf("%d", &T);
        while(T --)
        {
            scanf("%d%d%d", &n, &h, &k);
            for(int i = 1; i <= n; i ++)
            {
                for(int j = 1; j <= n; j ++)
                    sol.m[i][j] = INF;
            }
            for(int i = 0; i < h; i ++)
            {
                int u, v;LL c;
                scanf("%d%d", &u, &v); cin >> c;
                sol.m[u][v] = min(sol.m[u][v], c);
            }
            sol = Mul(sol, k);
            if(sol.m[1][n] == INF) puts("-1");
            else cout << sol.m[1][n] << endl;
            //printf("%lld
    ", sol.m[1][n]);
        }
    }
    
                     H题全然没想法,最后绝杀的那个人真厉害,ORZ~~


  • 相关阅读:
    调优Java virtual machine常见问题汇总整理
    Social Media POC KT Session
    框架Hibernate笔记系列 基础Session
    JVM相关命题的博客整理及总结
    项目总结笔记系列 wsTax KT Session1
    项目总结笔记系列 Autonomy IDOL Server KT Session1
    项目总结笔记系列 Maven Session2
    项目总结笔记系列 Maven Session1
    Data Structures/Algorithms 小甲鱼99讲笔记系列(1~~15讲)
    循环有序数组查找
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7121241.html
Copyright © 2011-2022 走看看