CSDN编程竞赛第9期题解

CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/22
(请不要删掉此地址)

1. 题目名称:小艺读书

        书是人类进步的阶梯。 小艺每周因为工作的原因会选择性的每天多读几页或者少读几页。 小艺想知道一本n页的书她会在周几读完。 

        由于题目数据范围小,根据题意模拟即可。

#include 
using namespace std;
int main()
{
    int n, p[10];
    scanf("%d", &n);
    for (int i = 0; i < 7; ++i)
        scanf("%d", p + i);
    int ans = -1, i = 0;
    while (n > 0)
    {
        n -= p[i];
        ++ans;
        if (ans >= 7)
            ans = 0;
        ++i;
        if (i >= 7)
            i = 0;
    }
    printf("%d\n", ans + 1);
    return 0;
}

2. 题目名称:鬼画符门之宗门大比

        给定整数序列A。求在整数序列A中连续权值最大的子序列的权值。

        根据题意,要求的是权值和最大的子区间。经典DP,设dp[i]为以 i 位置结尾的权值和最大的子区间。

dp[i] = max(dp[i-1],0)+a[i]

#include 
using namespace std;
const int maxn = 1010;
int a[maxn];
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    int ans = 0, now = 0;
    for (int i = 0; i < n; ++i)
    {
        ans = max(ans, max(0, now) + a[i]);
        now = max(0, now) + a[i];   // 就是dp[i]
    }
    printf("%d\n", ans);
    return 0;
}

3. 题目名称:硬币划分

        有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n<=100000),有多少种组合可以组成n分钱?

        ·可以用DP来解决,设dp[i] 为组成 i 分钱的组合数目,那么对于每种硬币,有:

dp[i]=dp[i]+dp[i-v[j]]

枚举每种硬币,从小到大刷背包容量即可。 

#include 
using namespace std;
const int maxn = 100010;
const int mod = 1e9 + 7;
int w[] = {1, 2, 5, 10};
int dp[maxn];
int main()
{
    int n;
    scanf("%d", &n);
    dp[0] = 1;
    for (int i = 0; i < 4; ++i)
    {
        for (int j = w[i]; j <= n; ++j)
        {
            dp[j] = (dp[j] + dp[j - w[i]]) % mod;
        }
    }
    printf("%d\n", dp[n]);
    return 0;
}

4. 题目名称:饿龙咆哮-逃离城堡

        小艺酱误入龙族结界,被恶龙带回城堡,小艺酱决定逃离城堡,逃离龙族结界.。 总路程为c, 小艺酱的速度是vp,饿龙速度为vd。饿龙会在t小时后发现小艺酱出逃。 小艺酱担心自己跑不出去,准备了好多珍宝。 每当饿龙追上自己的时候小艺酱就会丢下一个珍宝,饿龙捡到珍宝会返回自 己的城堡进行研究,研究f小时后,再出城堡追赶小艺。 小艺想知道自己至少需要丢多少珍宝才能让自己安全逃出结界。

         根据题意模拟即可,可以用将饿龙从城堡追上小艺酱这一过程放入循环计算。

#include 
using namespace std;
typedef long long ll;
int main()
{
    double vp, vd, t, f, c;
    scanf("%lf%lf%lf%lf%lf", &vp, &vd, &t, &f, &c);
    double s1 = vp * t, v = vd - vp;
    if (s1 >= c || v <= 0)
        return puts("0"), 0;
    int ans = 0;
    while (1)
    {
        if (s1 * vp >= v * (c - s1))
            break;
        ++ans;
        double s2 = s1 / v * vd;
        s1 += vp * (2 * s1 / v + f);
    }
    printf("%d\n", ans);
    return 0;
}

你可能感兴趣的:(题解,算法,c++,数据结构)