【codeforces ZeptoLab Code Rush 2015】ABCD题解

A. King of Thieves

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
In this problem you will meet the simplified model of game King of Thieves.

In a new ZeptoLab game called “King of Thieves” your aim is to reach a chest with gold by controlling your character, avoiding traps and obstacles on your way.

An interesting feature of the game is that you can design your own levels that will be available to other players. Let’s consider the following simple design of a level.

A dungeon consists of n segments located at a same vertical level, each segment is either a platform that character can stand on, or a pit with a trap that makes player lose if he falls into it. All segments have the same length, platforms on the scheme of the level are represented as ‘*’ and pits are represented as ‘.’.

One of things that affects speedrun characteristics of the level is a possibility to perform a series of consecutive jumps of the same length. More formally, when the character is on the platform number i1, he can make a sequence of jumps through the platforms i1 < i2 < … < ik, if i2 - i1 = i3 - i2 = … = ik - ik - 1. Of course, all segments i1, i2, … ik should be exactly the platforms, not pits.

Let’s call a level to be good if you can perform a sequence of four jumps of the same length or in the other words there must be a sequence i1, i2, …, i5, consisting of five platforms so that the intervals between consecutive platforms are of the same length. Given the scheme of the level, check if it is good.

Input
The first line contains integer n (1 ≤ n ≤ 100) — the number of segments on the level.

Next line contains the scheme of the level represented as a string of n characters ‘*’ and ‘.’.

Output
If the level is good, print the word “yes” (without the quotes), otherwise print the word “no” (without the quotes).

Sample test(s)
input
16
......*.
output
yes
input
11
....
output
no
Note
In the first sample test you may perform a sequence of jumps through platforms 2, 5, 8, 11, 14.

暴力枚举首相和公差,注意是五个点,跳四步。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
char s[1005];
int a[1005];
int main()
{
    int n;
    cin>>n;
    scanf("%s",s);
    for (int i=0;i<n;i++)
        if (s[i]=='*') a[i+1]=1;
        else a[i+1]=0;
    int f=0;
    for (int i=1;i+4<=n;i++)
    {
        for (int j=1;i+4*j<=n;j++)
        {
            int ok=1;
            for (int k=i;k<=i+4*j;k+=j)
                if (!a[k]) ok=0;
            if (ok) f=1;
        }
        if (f) break;
    }
    if (f) cout<<"yes"<<endl;
    else cout<<"no"<<endl;
    return 0;
}

B. Om Nom and Dark Park
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Om Nom is the main character of a game “Cut the Rope”. He is a bright little monster who likes visiting friends living at the other side of the park. However the dark old parks can scare even somebody as fearless as Om Nom, so he asks you to help him.

The park consists of 2n + 1 - 1 squares connected by roads so that the scheme of the park is a full binary tree of depth n. More formally, the entrance to the park is located at the square 1. The exits out of the park are located at squares 2n, 2n + 1, …, 2n + 1 - 1 and these exits lead straight to the Om Nom friends’ houses. From each square i (2 ≤ i < 2n + 1) there is a road to the square . Thus, it is possible to go from the park entrance to each of the exits by walking along exactly n roads.

To light the path roads in the evening, the park keeper installed street lights along each road. The road that leads from square i to square has ai lights.
Om Nom loves counting lights on the way to his friend. Om Nom is afraid of spiders who live in the park, so he doesn’t like to walk along roads that are not enough lit. What he wants is that the way to any of his friends should have in total the same number of lights. That will make him feel safe.

He asked you to help him install additional lights. Determine what minimum number of lights it is needed to additionally place on the park roads so that a path from the entrance to any exit of the park contains the same number of street lights. You may add an arbitrary number of street lights to each of the roads.

Input
The first line contains integer n (1 ≤ n ≤ 10) — the number of roads on the path from the entrance to any exit.

The next line contains 2n + 1 - 2 numbers a2, a3, … a2n + 1 - 1 — the initial numbers of street lights on each road of the park. Here ai is the number of street lights on the road between squares i and . All numbers ai are positive integers, not exceeding 100.

Output
Print the minimum number of street lights that we should add to the roads of the park to make Om Nom feel safe.

Sample test(s)
input
2
1 2 3 4 5 6
output
5
Note
Picture for the sample test. Green color denotes the additional street lights.
这里写图片描述

最后统一的路径长度一定是最长的那条路的长度。

代码中的Solve(l,r)是我考试的时候写的,非常暴力,能在最高层处理的就在最高层处理了,否则就递归处理。

主程序中没有被注释掉的是tourist考试中写的,直接从下往上迭代,和我的本质差不多,但是复杂度是 O(n) 的,代码也简单。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
int ans;
int a[10000],ma;
void Solve(int l,int r)
{
    if (l+1==r)
    {
        ans=ans+ma-a[l]+ma-a[r];
        return;
    }
    int m=(l+r)>>1;
    int x=0;
    for (int i=l;i<=m;i++)
        x=max(x,a[i]);
    x=ma-x;
    ans=ans+x;
    for (int i=l;i<=m;i++)
        a[i]+=x;
    x=0;
    for (int i=m+1;i<=r;i++)
        x=max(x,a[i]);
    x=ma-x;
    ans=ans+x;
    for (int i=m+1;i<=r;i++)
        a[i]+=x;
    Solve(l,m),Solve(m+1,r);
}
int main()
{
    ans=0;
    int n;
    cin>>n;
    n=1<<(n+1);
    for (int i=2;i<n;i++)
        scanf("%d",&a[i]);
    for (int i=n/2-1;i;i--)
    {
        int x=a[i*2],y=a[i*2+1];
        ans=ans+max(x,y)-min(x,y);
        a[i]+=max(x,y);
    }
    /*a[1]=0;
    for (int i=2;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        a[i]=a[i/2]+x;
    }
    ma=0;
    for (int i=n/2;i<n;i++)
        ma=max(ma,a[i]);
    Solve(n/2,n-1);*/
    cout<<ans<<endl;
    return 0;
}

C. Om Nom and Candies

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
A sweet little monster Om Nom loves candies very much. One day he found himself in a rather tricky situation that required him to think a bit in order to enjoy candies the most. Would you succeed with the same task if you were on his place?

One day, when he came to his friend Evan, Om Nom didn’t find him at home but he found two bags with candies. The first was full of blue candies and the second bag was full of red candies. Om Nom knows that each red candy weighs Wr grams and each blue candy weighs Wb grams. Eating a single red candy gives Om Nom Hr joy units and eating a single blue candy gives Om Nom Hb joy units.

Candies are the most important thing in the world, but on the other hand overeating is not good. Om Nom knows if he eats more than C grams of candies, he will get sick. Om Nom thinks that it isn’t proper to leave candy leftovers, so he can only eat a whole candy. Om Nom is a great mathematician and he quickly determined how many candies of what type he should eat in order to get the maximum number of joy units. Can you repeat his achievement? You can assume that each bag contains more candies that Om Nom can eat.

Input
The single line contains five integers C, Hr, Hb, Wr, Wb (1 ≤ C, Hr, Hb, Wr, Wb ≤ 109).

Output
Print a single integer — the maximum number of joy units that Om Nom can get.

Sample test(s)
input
10 3 5 2 3
output
16
Note
In the sample test Om Nom can eat two candies of each type and thus get 16 joy units.

很神奇的乱搞题。

①如果有一个 w 是大于n的,那么他的个数一定小于 n ,直接暴力枚举个数即可。

②如果两个 w 都小于n怎么办?
我们来看看两者的性价比:
假设 hbwb<hrwr ,那么就有

hbwr<hrwb
在这里我们把 w 看作个数,式子左边的代价为wrwb,式子右边的代价为 wbwr
也就是说用相同的代价我们吃 r 就可以了~
说明当b的个数超过 wr ,是 x 的时候,我们完全可以只留下x%wr,其他的用 b 代替一定不会劣!
因此只要枚举b个数到 wr 即可!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define LL long long
using namespace std;
LL ca,le,c,ha,hb,wa,wb;
int main()
{
    LL ans=0;
    cin>>c>>ha>>hb>>wa>>wb;
    if (wa<wb) swap(wa,wb),swap(ha,hb);
    if (wa>=30000)
    {
        for (int i=0;i<=c/wa;i++)
            ans=max(ans,i*ha+(c-i*wa)/wb*hb);
        cout<<ans<<endl;
        return 0;
    }
    double xa,xb;
    xa=(double)ha/wa;
    xb=(double)hb/wb;
    if (xa>xb) swap(ha,hb),swap(wa,wb);
    for (int i=0;i<=wb&&i*wa<=c;i++)
        ans=max(ans,i*ha+(c-i*wa)/wb*hb);
    cout<<ans<<endl;
    return 0;
}

D. Om Nom and Necklace

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
One day Om Nom found a thread with n beads of different colors. He decided to cut the first several beads from this thread to make a bead necklace and present it to his girlfriend Om Nelly.

Om Nom knows that his girlfriend loves beautiful patterns. That’s why he wants the beads on the necklace to form a regular pattern. A sequence of beads S is regular if it can be represented as S = A + B + A + B + A + … + A + B + A, where A and B are some bead sequences, ” + ” is the concatenation of sequences, there are exactly 2k + 1 summands in this sum, among which there are k + 1 “A” summands and k “B” summands that follow in alternating order. Om Nelly knows that her friend is an eager mathematician, so she doesn’t mind if A or B is an empty sequence.

Help Om Nom determine in which ways he can cut off the first several beads from the found thread (at least one; probably, all) so that they form a regular pattern. When Om Nom cuts off the beads, he doesn’t change their order.

Input
The first line contains two integers n, k (1 ≤ n, k ≤ 1 000 000) — the number of beads on the thread that Om Nom found and number k from the definition of the regular sequence above.

The second line contains the sequence of n lowercase Latin letters that represent the colors of the beads. Each color corresponds to a single letter.

Output
Print a string consisting of n zeroes and ones. Position i (1 ≤ i ≤ n) must contain either number one if the first i beads on the thread form a regular sequence, or a zero otherwise.

Sample test(s)
input
7 2
bcabcab
output
0000011
input
21 2
ababaababaababaababaa
output
000110000111111000011
Note
In the first sample test a regular sequence is both a sequence of the first 6 beads (we can take A = “”, B = “bca”), and a sequence of the first 7 beads (we can take A = “b”, B = “ca”).

In the second sample test, for example, a sequence of the first 13 beads is regular, if we take A = “aba”, B = “ba”.

kmp+思路题。

求出kmp的next数组(表示后缀与前缀的最长公共长度)。

首先要知道kmp的一个性质:
循环节的个数为 nnnext[n] ,如果结果是0的话循环节就是串本身了。
(证明在这里

对于这道题,我们 O(n) 求出 next[i] ,然后枚举每一位。

当前枚举到第 i 位时,我们可以根据求出的next数组, O(1) 计算出循环节长度为 inext[i] (假设他是S),循环节的个数为 c=iinext[i] ,接下来分两种情况讨论:

i%(inext[i])=0
说明当前的串是SSSS…SS这个样子,那么A串B串都是SS..SS(或者为空)。

则A串至少要用掉 c%k 个S;
而把A+B看成一个整体的话,要用掉 c/k 个S,我们只要判断 c/kc%k 是否大于等于0即可。

i%(inext[i])0
说明当前的串是SSSS…SST(T是S的前缀)这个样子,那么A串必然是SS…ST,而B串是(S-T)SS..S。

那么A至少要用掉 c%k 个S再加上一个T
还是把A+B看成一个整体,那么A+B要用掉 c/k 个S,因为B串不能为空了(他至少有一个(S-T)),所以需要判断 c/kc%k 是否大于0。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define N 1000005
#define LL long long
using namespace std;
char s[N];
int n,ne[N];
LL k;
int main()
{
    scanf("%d",&n);
    cin>>k;
    scanf("%s",s+1);
    int j=0;
    for (int i=2;i<=n;i++)
    {
        while (j&&s[i]!=s[j+1]) j=ne[j];
        if (s[i]==s[j+1]) j++;
        ne[i]=j;
    }
    for (int i=1;i<=n;i++)
    {
        LL c=i/(i-ne[i]);
        LL lenAB=c/k,lenA=c%k+((i%(i-ne[i]))!=0);
        if (lenAB-lenA>=0)
            printf("1");
        else printf("0");
    }
    printf("\n");
    return 0;
}

感悟:

觉得C题的思路很神奇,把 w <script type="math/tex" id="MathJax-Element-72">w</script>的含义变换成了个数,然后就很简单了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值