暑期集训 Contest 2

来源:互联网 发布:mp3网络歌曲免费下载 编辑:程序博客网 时间:2024/06/08 01:58

Glory And String

时间限制: 1 Sec  内存限制: 128 MB

题目描述

输入

First line is the number of strings T, the T lines follow, each line describe a string Glory needs to operate.The total length of strings won't exceed 5,000 and consist of only lower-case characters.The length of each string won't exceed 2,000.

输出

样例输入

3aaaababcdeabb

样例输出

141

把原串反过来跟原串做一次最长公共子序列,原串总长减去最长公共子序列就是答案。

#include<cstdio>
#include<cstring>
#include<algorithm>
usingnamespacestd;
constintmaxn = 5 * 1e3 + 5;
intdp[2][maxn];
chara[maxn],a1[maxn],c[maxn];
intmain()
{
    intt,n;
    scanf("%d",&t);
    while(t--)
    {
        intans = -1;
        scanf(" %s",a + 1);
        strcpy(c,a + 1);
        n =strlen(c);
        for(inti = 0;i <= n + 1; ++i) dp[0][i] = dp[1][i] = 0;
        for(inti = 1;i <= n; ++i) a1[i] = a[n + 1 - i];
        a1[0] =' ',a1[n + 1] ='\0';
        for(inti = 1;i <= n; ++i)
        {
            for(intj = 1;j <= n; ++j)
            {
                if(a[i] == a1[j]) dp[i % 2][j] = dp[(i - 1) % 2][j - 1] + 1;
                elsedp[i % 2][j] = max(dp[(i - 1) % 2][j],dp[i % 2][j - 1]);
                ans = max(ans,dp[i % 2][j]);
            }
        }
        printf("%d\n",n - ans);
    }
    return0;
}

W老师的玩具

时间限制: 2 Sec  内存限制:128 MB

题目描述

由于不小心让W老师在某道题上卡了十几发,A给W老师买了个玩具以表示歉意.

这个玩具可以看做一个多重集
最初,集合中只有一个元素0
每一轮,W老师会操作其中的每一个元素(设当前操作的为x)执行以下三种操作之一:
   
    1.  x=x+1
    2.  x分裂成两个非负整数a,b 即x=a+b,且a>=0,b>=0    
    3.  什么也不做

W老师玩了很久之后,已经不记得自己玩了多少轮了.

他很好奇自己最少玩多少轮才能把集合从开始变成现在的状态.

于是他把这个任务交给了A,如果A能找到答案他就会选择原谅他.但是A实在是太菜了,你能帮帮A吗?

输入

第一行,一个整数N,表示最终集合的大小

第二行为N个非负整数,表示最终集合的每一个元素

输出

一行,W老师最少玩的轮数

样例输入

41 1 1 1

样例输出

3

提示

单组数据

N<=1,000,000

0<=集合里的数字<=1,000,000


样例解释

第一轮:

0分裂成0 0

第二轮

0 0中每个0分裂成两个0,得到0 0 0 0

第三轮

每个0+1,得到1 1 1 1

逆序模拟一下即可,代码中体会吧。

#include<cstdio>
#include<cstring>
#include<algorithm>
usingnamespace std;
constint maxn = 1e6 + 5;
inta[maxn];
boolcmp(int x,inty)
{
    returnx > y;
}
intmain()
{
    intn;
    scanf("%d",&n);
    a[0] = -1;
    for(inti = 1;i <= n; ++i)scanf("%d",&a[i]);
    sort(a + 1,a + n + 1,cmp);
    intans = 0;
    intloc = n,num0 = 0;
    inttemp = a[n],cal = a[n];
    while(loc > 0)
    {
        temp = a[loc] - a[loc + 1];
        for(inti = 0;loc > 0 && i < temp && num0 > 1; ++i)
        {
            if(num0 & 1) ++num0;
            num0 >>= 1;
        }
        ans += temp;
        while(a[loc] == a[loc - 1]) --loc, ++num0;
        ++num0;
        --loc;
    }
    while(num0 > 1)
    {
        if(num0 & 1) ++num0;
        num0 >>= 1;
        ++ans;
    }
    printf("%d\n",ans);
    return0;
}

尧老师要教孩子玩球球

时间限制: 2 Sec  内存限制: 128 MB

题目描述

尧老师总是被他女朋友抱怨:还在玩ACM,玩个球啊!所以今天他和他的孩子要去房顶玩球。他们有 n 个球,半径分别为 ri。现将它们完全装入了内径为 R的烟囱(假设烟囱内部为圆柱),问烟囱高最小为多少。

输入

第一行包含一个整数 n (0 <= n <= 18)。

第二行包含 n 个整数 ri (0 < ri <= 1e4)。.

第三行包含一个整数 R(max(ri)<= R < 2 * min( ri ))。

输出

输出烟囱最小高度,保留两位小数。

样例输入

22 33

样例输出

9.90

正解是DP,打表找规律侥幸过了此题。。。规律是重新排序,把大的依次往两边放,从最大的开始,第一个最左边,第二个最右边,依次往中间靠,放完了都算一下就是答案。需要注意的是根据他的条件可以判断出一层只能放一个球,这样很大程度上简化了问题。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
usingnamespacestd;
constintmaxn = 20;
doublea[maxn],b[maxn];
boolcmp(doublex,double y)
{
    returnx > y;
}
intmain()
{
    intn;
    doubleR;
    scanf("%d",&n);
    if(n == 0)
    {
        printf("%.2f\n",0);
        return0;
    }
    for(inti = 0;i < n; ++i) scanf("%lf",&a[i]);
    scanf("%lf",&R);
    sort(a,a + n,cmp);
    doubleans = 0;
    intl = 0,r = n - 1,cou = 0;
    while(l <= r)
    {
        if(cou & 1) b[r--] = a[cou++];
        elseb[l++] = a[cou++];
    }
    ans = ans + b[0] + b[n - 1];
    for(inti = 0;i < n - 1; ++i)
    {
        ans = ans +sqrt(4 * R * (b[i] + b[i + 1] - R));
    }
    printf("%.2f\n",ans);
    return0;
}