Codeforces Round #269 (Div. 2) Solution

又趁夜撸了一发DIV2,然后由于困完挂了。

现在最终测试的结果还没有出来,估计写完就出来了。

通过了前四道题的Pretest.

update:这一次rank220,坑了!

A:给你六个长度(分别是四肢,头,躯干),让你判断这是什么物种。判断规则十分清楚了,然而我自己没注意看。。。导致被hack,并wa了数次。

思路:排序后直接找出四个相同的长度,若不存在为alien,否则剩下的两个相等elephant,再否则bear.

Code:

#include <cstdio>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;

int main() {
    int a[6];
    register int i, j;
    for(i = 0; i < 6; ++i)
        scanf("%d", &a[i]);
    sort(a, a + 6);

    int ins = -1;
    for(i = 0; i <= 2; ++i)
        if (a[i] == a[i + 1] && a[i + 1] == a[i + 2] && a[i + 2] == a[i + 3]) {
            ins = i;
            break;
        }

    if (ins == -1) {
        puts("Alien");
        return 0;
    }

    int tmp1, tmp2;
    if (ins == 0)
        tmp1 = a[4], tmp2 = a[5];
    if (ins == 1)
        tmp1 = a[0], tmp2 = a[5];
    if (ins == 2)
        tmp1 = a[0], tmp2 = a[1];

    if (tmp1 == tmp2)
        puts("Elephant");
    else
        puts("Bear");

    return 0;
}

B:有n项工作,每个工作都有一个difficulty,要求以difficulty不下降的顺序完成这些工作。若存在至少三种方案,输出其中的三种,否则输出no.

思路:首先排序后找出若干块连续的相同块,那么他们长度的阶乘积就是总的方案数,首先判断是否不超过3.

若存在3种方案,我们这样构造方案。

(1)直接就是排序后的标号序列

(2)在(1)基础上,找出第一个长度不为1的块交换前两个元素

(3)在(1)基础上,找出最后个长度不为1的块交换最后两个元素

不难证明这样做是正确的。

Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
using namespace std;

#define N 2010
struct Node {
    int lab, dif;
    Node(int _lab = 0, int _dif = 0):lab(_lab),dif(_dif){}
    bool operator < (const Node &B) const {
        return dif < B.dif;
    }
}S[N], S1[N], S2[N];

int begin[N], end[N], size[N], tot;
int main() {
    int n;
    scanf("%d", &n);
    register int i, j, k;
    int x;
    for(i = 1; i <= n; ++i) {
        scanf("%d", &x);
        S[i] = Node(i, x);
    }

    sort(S + 1, S + n + 1);
    S[n + 1].dif = -1 << 30;

    unsigned long long res = 1;
    bool find = 0;
    for(i = 1; i <= n;) {
        for(j = i; S[j].dif == S[j + 1].dif; ++j);
        size[++tot] = j - i + 1;
        begin[tot] = i;
        end[tot] = j;
        for(k = 2; k <= j - i + 1; ++k) {
            res *= k;
            if (res >= 3) find = 1;
        }
        i = j + 1;
    }

    if (!find) {
        printf("NO");
        return 0;
    }

    puts("YES");
    for(i = 1; i < n; ++i)
        printf("%d ", S[i].lab);
    printf("%d\n", S[n].lab);

    memcpy(S1, S, sizeof(S));
    for(i = 1; i <= tot; ++i)
        if (size[i] >= 2) {
            swap(S1[begin[i]], S1[begin[i] + 1]);
            break;
        }

    for(i = 1; i < n; ++i)
        printf("%d ", S1[i].lab);
    printf("%d\n", S1[n].lab);

    memcpy(S2, S, sizeof(S));
    for(i = tot; i >= 1; --i)
        if (size[i] >= 2) {
            swap(S2[end[i]], S2[end[i] - 1]);
            break;
        }

    for(i = 1; i < n; ++i)
        printf("%d ", S2[i].lab);
    printf("%d\n", S2[n].lab);

    return 0;
}

C:用指定张数的扑克牌搭建建筑,问可以搭建成多少种不同的层数。详细题意看原题。

显然若某一层有t个房间,那么这一层消耗的牌数为3*t-1

那么若一共s层,第i层房间数为ai,则总牌数为3*(a1+a2+...+as)-s

也就是说,我们首先判断(n+s)%3=0,则s符合条件。但是还要保证房间数递增,即a1>=1,ai>ai-1(2<=i<=s),于是a1+a2+...+as>=(1+s)*s/2

我们知道当(n+s)/3>=(1+s)*s/2时,我们总能构造出一组ai,使得其满足条件。反之则一定不能。

显然s在sqrt(n)范围内,因此枚举到10^6就可以了。

Code:

#include <cstdio>
#include <cstring>
#include <climits>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;

typedef long long LL;

int main() {
    LL n;
    scanf("%I64d", &n);

    int res = 0;
    register int i, j;
    for(i = 1; i <= 1000000 && i <= n; ++i) {
        if ((n + i) % 3 == 0) {
            LL last = (n + i) / 3;
            if (last >= (LL)i * (i + 1) / 2)
                ++res;
        }
    }

    printf("%d", res);

    return 0;
}

D:自己脑补= =

思路:差分后裸kmp串匹配,注意细节。

Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
using namespace std;

#define N 200010
int a1[N], a2[N], res[N], text[N], pre[N], dp[N];
bool end[N];

int main() {
    int n, w;
    scanf("%d%d", &n, &w);

    if (w == 1) {
        printf("%d", n);
        return 0;
    }
    if (n < w) {
        printf("0");
        return 0;
    }

    register int i, j;
    for(i = 1; i <= n; ++i)
        scanf("%d", &a1[i]);
    for(i = 1; i <= w; ++i)
        scanf("%d", &a2[i]);

    for(i = 1; i < w; ++i)
        res[i] = a2[i + 1] - a2[i];
    --w;
    for(i = 1; i < n; ++i)
        text[i] = a1[i + 1] - a1[i];
    --n;

    pre[1] = 0;
    j = 0;
    res[w + 1] = (int)1e9;
    for(i = 2; i <= w; ++i) {
        while(j && res[j + 1] != res[i])
            j = pre[j];
        if (res[j + 1] == res[i])
            ++j;
        pre[i] = j;
    }

    int tot = 0;
    j = 0;
    for(i = 1; i <= n; ++i) {
        while(j && res[j + 1] != text[i])
            j = pre[j];
        if (res[j + 1] == text[i])
            ++j;
        if (j == w)
            ++tot;
    }

    printf("%d\n", tot);

    return 0;
}
时间: 2024-08-28 14:47:05

Codeforces Round #269 (Div. 2) Solution的相关文章

Codeforces Round #275 (Div.1) Solution

好久没做题了,开场Virtual热热身. A 构造,我的方法是,取1,2,3...,k这几个差值,前k+1个数分别是 1, k+1, 2, k, ...., 之后就k+2, k+3, ..., n B 因为题设是与操作.我们按照每一位来,如果有一个限制某位是1,则将那段区间标志1,没有限制的位全部置零即可,然后检验为0的位是否全是1.标志一段区间可以用标记法,检验可以求和看差值. C 我做完之后看了CF tutorial 跟我的做法不同.我的做法比他给的复杂度低一点,不过题解好帅,而且跑出来速度

Codeforces Round #282 (Div.1) Solution

上午考试,下去去参观教堂,回来睡大觉,搞到现在才有时间做,水平恢复中. A 倒过来扫括号匹配很容易理解 B dp[i]表示最后一个拿到i的数目,sum[i]表示前i项dp和,sum2[i]表示前i项sum和.显然.dp[i]=sum2[o], o是最右边的坐标使得s[o+1,i]能包含t. C Interesting,我建了个树,硬着dp搞得..还没优化就46ms,想来这种题数据也不好构造. D Editorial似乎说离线搞,不过我在线搞出来了.我存了每个节点子树平方和,子树和,整体和,整体平

[比赛] Codeforces Round #538 (Div. 2) solution (贪心,数学其他,二分,线段树)

已经写了100篇题解啦! link solution pdf #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; inline int read(){ int f=1,ans=0;char c; while(c<'0'||c>'9'){if(c=='-')f=-1;c

Codeforces Round #607 (Div. 1) Solution

从这里开始 比赛目录 我又不太会 div 1 A? 我菜爆了... Problem A Cut and Paste 暴力模拟一下. Code #include <bits/stdc++.h> using namespace std; typedef bool boolean; const int N = 1e6 + 5; const int Mod = 1e9 + 7; int T; int x; int len; char s[N]; int paste(int s1, int t1, in

Codeforces Round #269 (Div. 2) D. MUH and Cube Walls KMP

D. MUH and Cube Walls Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got hold of lots of wooden cubes somewhere. They started making cube towers by placing the cubes one on top of the other. T

Codeforces Round #269 (Div. 2) B. MUH and Important Things

It's time polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got down to business. In total, there are n tasks for the day and each animal should do each of these tasks. For each task, they have e

Codeforces Round #268 (Div. 1) solution

A.24 Game 题意:给你1, 2, ..., n-1, n 这个序列,每次你可以取出两个数做+/-/*三种操作之一,然后把结果放回到序列中,询问能否是的这个序列最后只剩下一个24. 解法:首先很明显n < 4的时候是无解的.如果n=4,那么1 * 2 * 3 * 4=24,如果n=5,那么(5 - 1 - 2) * 3 * 4 = 24.若n > 5,那么我可以做n - (n - 1) = 1,相当于变成了n-2时候的情况加一个1,那么显然最后让答案乘上这个1即可. 代码: includ

Codeforces Round #276 (Div.1) Solution

水平越来越菜了 A  水题,注意后面全是1的情况 B  调和级数呀.把倍数全部扫一遍.一个数是多个数的倍数的话肯定是大的比较优.然后可以用two pointer扫一下. C  就是一个置换群,把轮换找出来就好了.傻逼的写了好久. D  有意思的傻逼DP,容易得到dp[i] = max{dp[j] + max{abs(a[k]-a[h])}} .只要更新一个U = max{a[i] + max_{0~(i-1)}{dp[i]}}和D = max{-a[i] + max_{0~(i-1)}{dp[i

Codeforces Round #283 (Div.1) Solution

A 贪心,从第一列开始一旦有不符合就把这列去掉.因为如果符合只可能使后面优势更大. B 枚举t就能找到局面了.因为调和级数的和是logn所以复杂度符合要求. C 将actor和part一起排好序,L小先,R大先,actor先.容易发现排在某个part后面的actor是不可能包含它的.它之后的part对于前面出现actor的L没有要求,于是每个part要尽量节约的使用R,于是找比自己R大最小的.set维护即可. D 题意是两个多边形围绕自己中心同样的角速度顺时针转,问有没有可能撞到.一眼就想到可以