AtCoder Beginner Contest 346

2024-03-24 18:52
文章标签 atcoder beginner contest 346

本文主要是介绍AtCoder Beginner Contest 346,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A. Adjacent Product(循环)

题意

给出 N N N个数字 A 1 , A 2 , … , A N A_1, A_2, \ldots, A_N A1,A2,,AN。定义 B i = A i × A i + 1 ( 1 ≤ i ≤ N − 1 ) B_i = A_i \times A_{i + 1}(1 \le i \le N - 1) Bi=Ai×Ai+1(1iN1)

请你打印 B 1 , B 2 , … , B N − 1 B_1, B_2, \ldots, B_{N - 1} B1,B2,,BN1

分析

输入后使用循环计算出 B B B数组中每一项的值,并将对应的值输出即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;int a[105];void solve() {int n;cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];}for (int i = 2; i <= n; i++) {if (i - 2) cout << ' ';cout << a[i - 1] * a[i];}cout << endl;
}int main() {solve();return 0;
}

B. Piano(暴力)

题意

给出一个以"wbwbwwbwbwbw"无限循环的字符串,问,能否取出该字符串中的一个子串,使得子串中字符'w'的出现次数恰好为 W W W,字符'b'的出现次数恰好为 B B B

思路1:构造字符串

可以将字符串拼接若干次,保证长度能够满足题目要求,然后检查该字符串中所有长度为 W + B W + B W+B的子串是否满足要求,如果满足要求,输出"Yes",否则,输出"No"

hint: 由于题目数据范围较小,因此枚举子串并检查的方法可以使用暴力枚举,前缀和,双指针等方式进行均可。

思路2:取模

由于字符串是循环的,那么字符串第 i i i个字符与第 i i % 12 i个字符是相同的,因此,不需要拼接字符串,直接对该长度为12的字符串进行枚举检查即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;string s = "wbwbwwbwbwbw";
string str = "";void solve() {while (str.size() < 20000) {str += s;}int W, B;cin >> W >> B;int w = 0, b = 0;for (int i = 0; i < W + B; i++) {if (str[i] == 'w') w++;else b++;}if (w == W && B == b) {cout << "Yes" << endl;return;} else {for (int i = W + B; i < str.size(); i++) {if (str[i] == 'w')  {w++;} else {b++;}if (str[i - W - B] == 'w') {w--;} else {b--;}if (w == W && B == b) {cout << "Yes" << endl;return;}}}cout << "No" << endl;
}int main() {solve();return 0;
}

C. Σ (set)

题意

给出 N N N个数字 A 1 , A 2 , … , A N A_1, A_2, \ldots, A_N A1,A2,,AN,问 1 ∼ K 1 \sim K 1K之间所有未在数组 A A A中出现的数字之和是多少?

分析

对于 1 ∼ K 1 \sim K 1K之间的数字之和,可以通过等差数量的求和公式直接得到( ( 1 + K ) × K 2 \frac{(1 + K) \times K}{2} 2(1+K)×K)。

然后考虑怎么减去范围内在数字 A A A中出现过的数字,由于数组 A A A中的数字可能出现重复,因此,需要对数组中的元素进行去重,可以使用set, map, unique等容器或函数来进行。

去重完成后,遍历剩余的元素,如果在 1 ∼ K 1 \sim K 1K范围内,就将这个数字从答案中减掉。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;set<int> S;void solve() {ll n, k;cin >> n >> k;for (int i = 1; i <= n; i++) {int a;cin >> a;S.insert(a);}ll ans = (1ll + k) * k / 2;for (auto i : S) {if (i > k) break;ans -= i;}cout << ans << endl;
}int main() {solve();return 0;
}

D. Gomamayo Sequence(DP)

题意

给出一个仅包含01的字符串,然后给出对于好字符串的定义:

  • 对于字符串中所有相邻的字符,如果只存在一对相邻的字符是相等的,那么就认为这个字符是好字符串。

对于字符串中第 i i i个字符,你可以花费 C i C_i Ci的费用将该字符变成另一个字符(0110),问,最少花费多少,可以使得字符串变成好字符串。

分析

考虑 D P DP DP,定义 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]为第 i i i个字符为 j j j k = 0 k = 0 k=0表示当前字符为 j j j时前面所有相邻的字符中未出现相同的, k = 1 k = 1 k=1表示当前字符为 j j j时前面所有字符中已经出现相同的。

转移方程:

  • 对于 d p [ i ] [ 0 ] [ 0 ] dp[i][0][0] dp[i][0][0],由于当前字符为0,且前面所有相邻字符均未出现相同的情况,那么能继承的只有上一个字符选择1,且也没有出现相邻相同的状态 d p [ i − 1 ] [ 1 ] [ 0 ] dp[i - 1][1][0] dp[i1][1][0]

  • 对于 d p [ i ] [ 1 ] [ 0 ] dp[i][1][0] dp[i][1][0],由于当前字符为1,且前面所有相邻字符均未出现相同的情况,那么能继承的只有上一个字符选择0,且也没有出现相邻相同的状态 d p [ i − 1 ] [ 0 ] [ 0 ] dp[i - 1][0][0] dp[i1][0][0]

  • 对于 d p [ i ] [ 0 ] [ 1 ] dp[i][0][1] dp[i][0][1],由于当前字符为0,且包含当前字符时已经出现相邻相同的情况了,那么就可以分为以下两种情况,选择两种情况中的较小值:

    • 前面没有出现相邻相同的情况,但当前字符与上一个字符相同,此时刚好出现相邻相同的情况: d p [ i − 1 ] [ 0 ] [ 0 ] dp[i - 1][0][0] dp[i1][0][0]

    • 前面已经出现相邻相同的情况,此时字符必须与前一个字符不同: d p [ i − 1 ] [ 1 ] [ 1 ] dp[i - 1][1][1] dp[i1][1][1]

  • 对于 d p [ i ] [ 1 ] [ 1 ] dp[i][1][1] dp[i][1][1],由于当前字符为1,且包含当前字符时已经出现相邻相同的情况了,那么就可以分为以下两种情况,选择两种情况中的较小值:

    • 前面没有出现相邻相同的情况,但当前字符与上一个字符相同,此时刚好出现相邻相同的情况: d p [ i − 1 ] [ 1 ] [ 0 ] dp[i - 1][1][0] dp[i1][1][0]

    • 前面已经出现相邻相同的情况,此时字符必须与前一个字符不同: d p [ i − 1 ] [ 0 ] [ 1 ] dp[i - 1][0][1] dp[i1][0][1]

hint:

  1. 如果 j j j与当前字符不同,需要加上修改字符的费用。

  2. 只有 i > 1 i > 1 i>1时,才可能出现 k = 1 k = 1 k=1的情况,因此 i = 1 i = 1 i=1时, d p [ 1 ] [ j ] [ 1 ] dp[1][j][1] dp[1][j][1]不能继承状态,可以将所有 d p [ 0 ] [ j ] [ 1 ] dp[0][j][1] dp[0][j][1] d p [ 1 ] [ j ] [ 1 ] dp[1][j][1] dp[1][j][1]初始化为极大值,并在状态转移时特判跳过。

结束状态转移后,由于要求必须存在恰好一对相邻相同的情况,因此答案为 m i n ( d p [ n ] [ 0 ] [ 1 ] , d p [ n ] [ 1 ] [ 1 ] ) min(dp[n][0][1], dp[n][1][1]) min(dp[n][0][1],dp[n][1][1])

代码

#include <bits/stdc++.h>using namespace std;
typedef long long ll;ll n, c[200005], dp[200005][2][2];
string s;int main() {cin >> n >> s;s = "#" + s;for (int i = 1; i <= n; i++) {cin >> c[i];}dp[0][0][1] = dp[0][1][1] = dp[1][0][1] = dp[1][1][1] = 0x3f3f3f3f3f3f3f3f;for (int i = 1; i <= n; i++) {if (s[i] == '0') {dp[i][0][0] = dp[i - 1][1][0];dp[i][1][0] = dp[i - 1][0][0] + c[i];if (i == 1) continue;dp[i][0][1] = min(dp[i - 1][1][1], dp[i - 1][0][0]);dp[i][1][1] = min(dp[i - 1][1][0], dp[i - 1][0][1]) + c[i];} else {dp[i][0][0] = dp[i - 1][1][0] + c[i];dp[i][1][0] = dp[i - 1][0][0];if (i == 1) continue;dp[i][0][1] = min(dp[i - 1][1][1], dp[i - 1][0][0]) + c[i];dp[i][1][1] = min(dp[i - 1][1][0], dp[i - 1][0][1]);}}cout << min(dp[n][0][1], dp[n][1][1]) << endl;return 0;
}

E. Paint(思维)

题意

有一个 H H H W W W列的网格,开始时,所有的格子都被涂上了颜色0

你将在 i = 1 , 2 , … , M i = 1, 2, \ldots, M i=1,2,,M时执行以下操作:

  • 如果 T i = 1 T_i = 1 Ti=1,将第 A i A_i Ai行涂成颜色 X i X_i Xi

  • 如果 T i = 2 T_i = 2 Ti=2,将第 A i A_i Ai列涂成颜色 X i X_i Xi

请你输出操作结束后网格上剩余的颜色以及这些颜色所占的网格数量。

分析

对于每个网格结束操作后的颜色,实际上只取决于最后一次操作时涂上的颜色,因此,可以对每一行,每一列的操作进行标记,如果后面操作过了这一行或这一列,那么前面对这一行或这一列的操作就可以忽略了。

因此,可以从后往前遍历操作,如果当前操作的行和列没被涂色过,就将该行(或列)进行标记,并记录当前涂上的颜色的个数(涂行就记录剩余列数,涂列就记录剩余行数)。

然后对于每个涂色操作,可以将被涂色的行(或列)视为涂完色后就被删除了,那么每次涂色就是对于剩余部分的行数(或列数)进行涂色的,也便于计算每个颜色的个数。

结束涂色后,剩余的行数 × \times ×列数就是颜色0的数量。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;ll H, W, M, h[200005], w[200005], t[200005], a[200005], x[200005];ll vis[200005], cnt[200005];vector<pair<ll, ll> > ans;int main() {cin >> H >> W >> M;for (int i = 1; i <= M; i++) {cin >> t[i] >> a[i] >> x[i];}for (int i = M; i >= 1; i--) {if (t[i] == 1) {if (!h[a[i]]) {h[a[i]] = 1;cnt[x[i]] += W;H--;}} else {if (!w[a[i]]) {w[a[i]] = 1;cnt[x[i]] += H;W--;}}}cnt[0] += H * W;for (int i = 0; i <= 2e5; i++) {if (cnt[i]) {ans.push_back(make_pair(i, cnt[i]));}}cout << ans.size() << endl;for (auto i : ans) {cout << i.first << ' ' << i.second << endl;}return 0;
}

F ∼ G F \sim G FG,更新中…

赛后交流

在比赛结束后,会在交流群中给出比赛题解,同学们可以在赛后查看题解进行补题。

群号: 704572101,赛后大家可以一起交流做题思路,分享做题技巧,欢迎大家的加入。

这篇关于AtCoder Beginner Contest 346的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/842465

相关文章

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||

2014 Multi-University Training Contest 6小记

1003  贪心 对于111...10....000 这样的序列,  a 为1的个数,b为0的个数,易得当 x= a / (a + b) 时 f最小。 讲串分成若干段  1..10..0   ,  1..10..0 ,  要满足x非递减 。  对于 xi > xi+1  这样的合并 即可。 const int maxn = 100008 ;struct Node{int

AtCoder Beginner Contest 370 Solution

A void solve() {int a, b;qr(a, b);if(a + b != 1) cout << "Invalid\n";else Yes(a);} B 模拟 void solve() {qr(n);int x = 1;FOR(i, n) FOR(j, i) qr(a[i][j]);FOR(i, n) x = x >= i ? a[x][i]: a[i][x];pr2(

CF Bayan 2015 Contest Warm Up B.(dfs+暴力)

B. Strongly Connected City time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/probl

CF Bayan 2015 Contest Warm Up A.(模拟+预处理)

A. Bayan Bus time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/problem/A The fi

AtCoder Beginner Contest 369 D - Bonus EXP 动态规划

原题链接: https://atcoder.jp/contests/abc369/tasks/abc369_d 思路:   这道题为什么要用动态规划呢,其实,对于第i个怪物,我们有打与不打两种处理方式,而对于打,我们是获得两倍的经验值,还是一倍的经验值,与我们打了奇数只怪物还是打了偶数只怪物有关了,因此我们定义dp[i][0] 为前i只怪物总共打了偶数次,dp[i][1] 为前i只怪物总

2015 Multi-University Training Contest 5 1009 MZL#39;s Border

MZL's Border  Problem's Link:  http://acm.hdu.edu.cn/showproblem.php?pid=5351   Mean:  给出一个类似斐波那契数列的字符串序列,要你求给出的f[n]字符串中截取前m位的字符串s中s[1...i] = s[s.size()-i+1....s.size()]的最大长度。 analyse:   过计算

【UVa】10600 ACM Contest and Blackout 次小生成树

类型:次小生成树 题目大意: 为了举办ACM竞赛,市长决定给所有的n(3 <= n <= 100)所学校提供可靠的电力供应。当且仅当一个学校直接连到电站,或者连到另一个有可靠供应的学校时,才有可靠供应。现在给出在不同学校之间的布线成本,找出最便宜的两种连线方案。一个方案的成本等于其中所有学校之间连线的成本的总和。 题目分析: 次小生成树。 先求出最小生成树,然后枚举所有不在

【POJ】3660 Cow Contest floyd(可以拓扑排序?)

Cow Contest Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6925 Accepted: 3792 Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating i