The 14th Zhejiang University Programming Contest

              

132 - The 14th Zhejiang University Programming Contest
SolvedIDTitle Ratio (AC/All)
YesAElevator 71.77% (478/666)
YesBContinuous Login 14.97% (102/681)
CDiablo III 18.04% (24/133)
YesDRanking System 30.96% (296/956)
EEasy 2048 0.00% (0/4)
YesFCalculate the Function 21.16% (51/241)
GPaint the Grid 0.00% (0/27)
HPower of Fibonacci 15.38% (2/13)
YesI?(>_o)! 26.56% (292/1099)

               A题签到题。

               B题打表发现,每个数都最多由三段组成,然后最小的一段不超过100,然后就变成大水题了。。

#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 = 20000;
const int INF = 123456789;

map<int, int > mp;

int sum[maxn];

int main()
{
    sum[0] = 0;
    for(int i = 1; i < maxn; i ++)
    {
        sum[i] = sum[i - 1] + i;
        mp[sum[i]] = i;
    }
    int n, T = 0, a1, a2, a3;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d", &n);
        for(int i = 0; i < 100; i ++)
        {
            for(int j = 0; sum[i] + sum[j] <= n; j ++)
            {
                int tmp = sum[i] + sum[j];
                if(mp.count(n - tmp))
                {
                    a1 = i, a2 = j, a3 = mp[n-tmp];
                    goto ed;
                }
            }
        }
        ed:;
        bool flag = false;
        if(a1) printf("%d", a1), flag = true;
        if(a2)
        {
            if(flag) putchar(' ');
            printf("%d", a2);
            flag = true;
        }
        if(a3)
        {
            if(flag) putchar(' ');
            printf("%d", a3);
        }
        puts("");
    }
}

                 C题应该是母函数吧。比赛时TLE了n次没过。。。=.=!!!赛后优化了一下就过了。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <stack>
#include<map>
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define E exp(double(1))
#define eps 1e-7
using namespace std;

#ifdef __int64
typedef __int64 LL;
#else
typedef long long LL;
#endif
const int maxn = 50500;

char ch[30][30] =
{
    "Head", "Shoulder", "Neck", "Torso", "Hand",
    "Wrist", "Waist", "Legs", "Feet", "Finger",
    "Shield", "Weapon", "Two-Handed"
};


map<string, int> mp;
int fig[maxn];
int eng[2][maxn];
vector<int> d[20], t[20];

void init()
{
    for(int i = 0; i < 13; i ++) mp[ch[i]] = i, d[i].clear(), t[i].clear();

    for(int i = 0; i < 13; i ++) d[i].push_back(0), t[i].push_back(0);
}

int main()
{
    int T, n, m;
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d%d", &n, &m);
        init();
        for(int i = 0; i < n; i ++)
        {
            char op[20];
            int dd, tt;
            scanf("%s%d%d", op, &dd, &tt);
            int id = mp[op];
            d[id].push_back(dd);
            t[id].push_back(tt);
        }
        memset(fig, 0, sizeof(fig));
        int sz = d[9].size();
        for(int i = 0; i < sz; i ++)
            for(int j = i + 1; j < sz; j ++)
            {
                int tmp = d[9][i] + d[9][j];
                tmp = min(tmp, m);
                fig[tmp] = max(fig[tmp], t[9][i] + t[9][j]);
            }
        d[9].clear();t[9].clear();
        int mx = 0;
        for(int i = m; i >= 0; i --)
        {
            if(fig[i] && fig[i] > mx)
            {
                d[9].push_back(i);
                t[9].push_back(fig[i]);
                mx = fig[i];
            }
        }
        d[9].push_back(0), t[9].push_back(0);
        for(int i = 0; i < 2; i ++)
            for(int j = 0; j <= m; j ++) eng[i][j] = -1;
        int now = 0;
        eng[1][0] = 0;
        for(int i = 0; i < 10; i ++)
        {
            for(int j = 0; j <= m; j ++) eng[now][j] = -1;
            for(int j = 0; j <= m; j ++) if(eng[now^1][j] != -1)
                {
                    int sz = d[i].size();
                    for(int k = 0; k < sz; k ++)
                    {
                        if(t[i][k] + j >= m)
                        {
                            eng[now][m] = max(d[i][k] + eng[now^1][j], eng[now][m]);
                        }
                        else
                        {
                            int tmp = t[i][k] + j;
                            eng[now][tmp] = max(d[i][k] + eng[now^1][j], eng[now][tmp]);
                        }
                    }
                }
            now ^= 1;
        }
//        for(int j = 0; j <= m; j ++) eng[now][j] = -1;
//        for(int j = 0; j <= m; j ++) if(eng[now^1][j] != -1)
//            {
//                int sz = d[9].size();
//                for(int k = 0; k < sz; k ++)
//                    for(int kk = k+1; kk < sz; kk ++) if(k != kk)
//                        {
//                            if(t[9][k] + t[9][kk] + j >= m)
//                            {
//                                eng[now][m] = max(d[9][k] + d[9][kk] + eng[now^1][j], eng[now][m]);
//                            }
//                            else
//                            {
//                                int tmp = t[9][k] + j + t[9][kk];
//                                eng[now][tmp] = max(d[9][k] + d[9][kk] + eng[now^1][j], eng[now][tmp]);
//                            }
//                        }
//            }
//        now ^= 1;
        int ans = -2;

        for(int j = 0; j <= m; j ++) eng[now][j] = -1;
        for(int j = 0; j <= m; j ++) if(eng[now^1][j] != -1)
            {
                int sz = d[12].size();
                for(int k = 0; k < sz; k ++)
                {
                    if(t[12][k] + j >= m)
                    {
                        eng[now][m] = max(d[12][k] + eng[now^1][j], eng[now][m]);
                    }
                    else
                    {
                        int tmp = t[12][k] + j;
                        eng[now][tmp] = max(d[12][k] + eng[now^1][j], eng[now][tmp]);
                    }
                }
            }
        ans = max(ans, eng[now][m]);
        for(int i = 10; i < 12; i ++)
        {
            for(int j = 0; j <= m; j ++) eng[now][j] = -1;
            for(int j = 0; j <= m; j ++) if(eng[now^1][j] != -1)
                {
                    int sz = d[i].size();
                    for(int k = 0; k < sz; k ++)
                    {
                        if(t[i][k] + j >= m)
                        {
                            eng[now][m] = max(d[i][k] + eng[now^1][j], eng[now][m]);
                        }
                        else
                        {
                            int tmp = t[i][k] + j;
                            eng[now][tmp] = max(d[i][k] + eng[now^1][j], eng[now][tmp]);
                        }
                    }
                }
            now ^= 1;
        }
        ans = max(ans, eng[now^1][m]);
        printf("%d\n", ans);
    }
}


                 D题水题。

                 F题可以把递推式写成矩阵乘法,然后用倍增处理从L位置开始到达位置需要乘的矩阵,然后就直接倍增就可以了。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <stack>
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define E exp(double(1))
#define eps 1e-7
using namespace std;

#ifdef __int64
    typedef __int64 LL;
#else
    typedef long long LL;
#endif

const int maxn = 100100;
const LL mod = 1000000007;

struct Maxtr
{
    LL m[2][2];

    void pt()
    {
        puts("~~~~~~~~~~~~~~~~~~~");
        for(int i = 0; i < 2; i ++)
        {
            for(int j = 0; j < 2; j ++)
            printf("%lld ", m[i][j]);puts("");
        }
        puts("*******************");
    }
}T[maxn][20], pre;

Maxtr Mul(Maxtr a, Maxtr b)
{
    Maxtr ret;
    for(int i = 0; i < 2; i ++)
    {
        for(int j = 0; j < 2; j ++)
        {
            ret.m[i][j] = 0;
            for(int k = 0; k < 2; k ++)
            {
                ret.m[i][j] += a.m[i][k] * b.m[k][j];
            }
            ret.m[i][j] %= mod;
        }
    }
    return ret;
}

LL A[maxn];

int main()
{
    int n, M, t;
    scanf("%d", &t);
    for(int i = 0; i < 2; i ++)
        for(int j = 0; j < 2; j ++)
            pre.m[i][j] = (i == j);
    while(t --)
    {
        scanf("%d%d", &n, &M);
        for(int i = 1; i <= n; i ++)
        {
            scanf("%lld", &A[i]);
        }
        for(int i = 1; i <= n; i ++)
        {
            T[i][0].m[0][0] = 0;
            T[i][0].m[0][1] = A[i];
            T[i][0].m[1][0] = 1;
            T[i][0].m[1][1] = 1;
        }
        for(int j = 1; (1 << j) <= n; j ++)
        {
            for(int i = 1; i + (1 << (j - 1)) <= n; i ++)
            {
                T[i][j] = Mul(T[i][j - 1], T[i + (1 << (j - 1))][j - 1]);
            }
        }
        for(int i = 0; i < M; i ++)
        {
            int l, r;LL f1, f2;
            scanf("%d%d", &l, &r);
            if(l == r)
            {
                printf("%lld\n", A[l] % mod);
                continue;
            }
            f1 = A[l], f2 = A[l + 1];
            int ca = r - l - 1, now = l + 2;
            Maxtr mu = pre;
            for(int i = 20; i >= 0; i --) if((1 << i) & ca)
            {
                mu = Mul(mu, T[now][i]);
                now += (1 << i);
            }
            LL ans = f1 * mu.m[0][1] + f2 * mu.m[1][1];
            printf("%lld\n", ans % mod);
        }
    }
}

               I题水题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值