Atcoder Beginner Contest 346

比赛链接

A - Adjacent Product

时间限制:2秒        内存限制:1024MB

分数:100分

问题描述

给定 N 个整数 A_{1}, A_{2}, \cdots, A_{N}。同时,定义B_{i} = A_{i} \times A_{i + 1} (1 \leq i \leq N - 1)

按照 B_{1}, B_{2}, \cdots, B_{N - 1} 的顺序输出,用空格分隔。

限制

  • 2 \leq N \leq 100
  • 1 \leq A_{i} \leq 100
  • 所有输入的值都是整数

输入

输入以以下标准输入格式给出:

N\\ A_{1} \hspace{1em} A_{2} \hspace{1em} \cdots \hspace{1em} A_{N}

输出

按照 B_{1}, B_{2}, \cdots, B_{N - 1} 的顺序输出,用空格分隔。

样例输入输出

样例输入1

3\\ 3 \hspace{0.5em} 4 \hspace{0.5em} 6

样例输出1

12 \hspace{0.5em} 24

B_{1} = A_{1} \times A_{2}, B_{2} = A_{2} \times A_{3}

样例输入2

5\\ 22 \hspace{0.5em} 75 \hspace{0.5em} 26 \hspace{0.5em} 45 \hspace{0.5em} 72

样例输出2

1650 \hspace{0.5em} 1950 \hspace{0.5em} 1170 \hspace{0.5em} 3240

代码

#include <bits/stdc++.h>
using namespace std;

int n, a[120];

inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') x = x * 10 +c - '0', c = getchar();
    return x * f;
}

int main() {
    n = read();
    for (int i = 1; i <= n; i++) a[i] = read();
    for (int i = 1; i <= n - 1; i++) {
        printf("%d", a[i] * a[i + 1]);
        if (i != n - 1) printf(" ");
    }
    return 0;
}

B - Piano

时间限制:2秒        内存限制:1024MB

分数:200分

问题描述

问题陈述
有一个无限长的钢琴键盘。是否存在一个连续的片段,其中包含 W 个白键和 B 个黑键?

设 S 为通过无限重复字符串 wbwbwwbwbwbw 形成的字符串。

是否存在 S 的一个子字符串,其中包含 W 个 w(白键)和 B 个 b(黑键)?

限制

  • W 和 B 都是整数.
  • 0 \leq W,B \leq 100
  • W + B \geq 1

输入

输入以以下标准输入格式给出:

输出

如果存在 S 的一个子字符串,其中包含 W 个 w(白键)和 B 个 b(黑键),则输出 Yes;否则,输出 No。

样例输入输出

样例输入1

3 \hspace{0.5em} 2

样例输出1

Yes

字符串 S 的前 15 个字符是 wbwbwwbwbwbwwbw。你可以取第 11 到第 15 个字符形成子字符串 bwwbw,其中包含 3 个 w 和 2 个 b。

样例输入2

3 \hspace{0.5em} 0

样例输出2

No

唯一包含 3 个 w 和 0 个 b 的字符串是 www,它不是 S 的子字符串。

样例输入3

92 \hspace{0.5em} 66

样例输出3

Yes

思路

从被重复的字符串的每一位开始往后枚举,判断是否有符合条件的子字符串

代码

#include <bits/stdc++.h>
using namespace std;

int w, b;
char s[30] = "wbwbwwbwbwbwwbw";

inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

int main() {
    w = read(), b = read();
    for (int i = 0; i < 12; i++) {
        int len = 1, w1 = 0, b1 = 0;
        for (int j = i; len <= w + b; j = (j + 1) % 12, len++) {
            if (s[j] == 'w') w1++;
            if (s[j] == 'b') b1++;
        }
        if (w1 == w && b1 == b) {
            printf("Yes\n");
            return 0;
        }
    }
    printf("No\n");
    return 0;
}

C - Σ

时间限制:2秒        内存限制:1024MB

分数:250分

问题描述

给定一个由正整数组成的序列 A = (A_{1}, A_{2}, \cdots, A_{N}),其长度为 N,以及一个正整数 K。

找出在 1 到 K(包括 1 和 K)之间的整数中,那些没有出现在序列 A 中的整数的和。

限制

  • 1 \leq N \leq 2 \times 10^{5}
  • 1 \leq K \leq 2 \times 10^{9}
  • 1 \leq A_{i} \leq 2 \times 10^{9}
  • 所有输入的值都是整数

输入

输入是从标准输入以以下格式给出的:

N \hspace{0.5em} K\\ A_{1} \hspace{0.5em} A_{2} \hspace{0.5em} \hdots \hspace{0.5em} A_{N}

输出

输出答案

样例输入输出

样例输入1

4 \hspace{0.5em} 5\\ 1 \hspace{0.5em} 6 \hspace{0.5em} 3 \hspace{0.5em} 1

样例输出1

11

在 1 到 5 之间的整数中,有三个数字 2,4 和 5 没有出现在集合 A 中。

因此,输出出它们的和:2 + 4 + 5 = 11。

样例输入2

1 \hspace{0.5em} 3\\ 346

样例输出2

6

样例输入3

10 \hspace{0.5em} 158260522\\ 877914575 \hspace{0.5em} 24979445 \hspace{0.5em} 623690081 \hspace{0.5em} 262703497 \hspace{0.5em} 24979445 \hspace{0.5em} 1822804784 \hspace{0.5em} 1430302156 \hspace{0.5em} 1161735902 \hspace{0.5em} 923078537 \hspace{0.5em} 1189330739

样例输出3

12523196466007058

思路

首先用等差数列求和公式 \tfrac{k(k + 1)}{2} 求出1到k的和,再减去其中出现过的数就好了。

代码

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 2e5 + 10;
int n, k, a[N], b[N], ans = 0LL;

inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') x = x * 10 +c - '0', c = getchar();
    return x * f;
}

signed main() {
    n = read(), k = read();
    for (int i = 1; i <= n; i++) a[i] = read();
    sort(a + 1, a + n + 1);
    int size = 0, p = 1;
    for (int i = 1; i <= n; i++) {
        if (a[i] != a[i - 1]) b[++size] =a[i];
    } //去重
	ans = (k + 1) * k / 2; // 1到k所有数的和
	for (int i = 1; i <= size; i++) {
		if (b[i] <= k) ans -= b[i]; //减去1到k之间出现过的数
	} 
    printf("%lld\n", ans);
    return 0;
}

D - Gomamayo Sequence

时间限制:2秒        内存限制:1024MB

分数:400分

问题描述

给定一个长度为 N 的字符串 S该,字符串仅由 0 和 1 组成。

一个长度为 N 的字符串 T 被称为好字符串,当且仅当满足以下条件:

存在且仅存在一个整数 i,满足 1 \leq i \leq N - 1,使得 T 中的第 i 个字符和第 (i + 1) 个字符相同。

对于每个 i=1,2,…,N,你可以选择是否执行以下操作一次:

如果 S 中的第 i 个字符是 0,则将其替换为 1,反之亦然。如果执行了这个操作,那么该操作的代价是 C_{i}

找出使 S 成为好字符串所需的最小总代价。

限制

  • 2 \leq N \leq 2 \times 10^{5}
  • S 是长度为 N 的由 0 和 1 组成的字符串。
  • 1 \leq C_{i} \leq 10^{9}
  • N 和 C_{i} 都是整数。

输入

输入是从标准输入以以下格式给出的:

N\\ S\\ C_{1} \hspace{0.5em} C_{2} \hspace{0.5em} \hdots \hspace{0.5em} C_{N}

输出

输出答案

样例输入输出

样例输入1

5\\ 00011\\ 3 \hspace{0.5em} 9 \hspace{0.5em} 2 \hspace{0.5em} 6 \hspace{0.5em} 4

样例输出1

7

对于 i = 1, 5执行操作,但对于 i = 2, 3, 4不执行,这将得到字符串 S = 10010,这是一个好字符串。在这种情况下,所产生的成本是 7,并且不可能以少于 7 的成本使 S 成为一个好字符串,所以打印 7。

样例输入2

4\\ 1001\\ 1 \hspace{0.5em} 2 \hspace{0.5em} 3 \hspace{0.5em} 4

样例输出2

0

样例输入3

11\\ 11111100111\\ 512298012 \hspace{0.5em} 821282085 \hspace{0.5em} 543342199 \hspace{0.5em} 868532399 \hspace{0.5em} 690830957 \hspace{0.5em} 973970164 \hspace{0.5em} 928915367 \hspace{0.5em} 954764623 \hspace{0.5em} 923012648 \hspace{0.5em} 540375785 \hspace{0.5em} 925723427

样例输出3

2286846953

思路

代码

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 2e5 + 10;
int n, c[N], f[N][2][2];
char s[N];

inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}

signed main() {
	n = read(); scanf("%s", s);
	for (int i = 0; i < n; i++) c[i] = read(), f[i][0][0] = f[i][0][1] = f[i][1][0] = f[i][1][1] = INT_MAX;
	if (s[0] == '0') {
		f[0][0][0] = 0, f[0][1][0] = c[0];
	} else {
		f[0][1][0] = 0, f[0][0][0] = c[0];
	}
	for (int i = 1; i < n; i++) {
		if (s[i] == '0') {
			f[i][0][0] = f[i - 1][1][0], f[i][1][0] = f[i - 1][0][0] + c[i];
			f[i][0][1] = min(f[i - 1][1][1], f[i - 1][0][0]);
			f[i][1][1] = min(f[i - 1][1][0], f[i - 1][0][1]) + c[i];
		} else if (s[i] == '1') {
			f[i][1][0] = f[i - 1][0][0], f[i][0][0] = f[i - 1][1][0] + c[i];
			f[i][1][1] = min(f[i - 1][0][1], f[i - 1][1][0]);
			f[i][0][1] = min(f[i - 1][0][0], f[i - 1][1][1]) + c[i];
		}
	}
	printf("%lld", min(f[n - 1][0][1], f[n - 1][1][1]));
	return 0;
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值