Educational Codeforces Round 81 (Rated for Div. 2)
- 2020 年 2 月 17 日
- 笔记
B. Infinite Prefixes
无限前缀
You are given string ? of length ? consisting of 0-s and 1-s. You build an infinite string ? as a concatenation of an infinite number of strings ?, or ?=????… For example, if ?= 10010, then ?= 100101001010010… 给定字符串s,s由0和1组成。创建一个字符串t,t=ssss…,例如,如果s=10010,那么t=100101001010010…
Calculate the number of prefixes of ? with balance equal to ?. The balance of some string ? is equal to ???0,?−???1,?, where ???0,? is the number of occurrences of 0 in ?, and ???1,? is the number of occurrences of 1 in ?. The number of such prefixes can be infinite; if it is so, you must say that. 对于t的前缀字符串q,满足0的数量减去1的数量为x。
A prefix is a string consisting of several first letters of a given string, without any reorders. An empty prefix is also a valid prefix. For example, the string "abcd" has 5 prefixes: empty string, "a", "ab", "abc" and "abcd". 字符串前缀可以为空,比如字符串abcd有5个前缀:空, a, ab, abc, abcd
Input The first line contains the single integer ? (1≤?≤100) — the number of test cases. 第一行是用例数量T
Next 2? lines contain descriptions of test cases — two lines per test case. The first line contains two integers ? and ? (1≤?≤105, −109≤?≤109) — the length of string ? and the desired balance, respectively.
第二行是字符串s The second line contains the binary string ? (|?|=?, ??∈{0,1}).
It's guaranteed that the total sum of ? doesn't exceed 105.
OutputPrint ? integers — one per test case. For each test case print the number of prefixes or −1 if there is an infinite number of such prefixes.
Example
input 4 6 10 010010 5 3 10101 1 0 0 2 0 01
output 3 0 1 -1
Note In the first test case, there are 3 good prefixes of ?: with length 28, 30 and 32.
解题思路
考虑两种情况,s的0和1数量相等和不相等 相等的时候是两个极端,存在即无限,不存在就是0 不相等的时候是求出满足条件的个数
这道题理解起来比较简单,主要是要考虑清楚几种情况,然后小心计算不相等时的个数。
C++源代码
#include <iostream> #include <vector> #include <map> #include <set> #include <queue> #include <algorithm> #include <string> #include <cmath> #include <cstdio> #include <iomanip> #include <fstream> #include <cassert> #include <cstring> #include <unordered_set> #include <unordered_map> #include <numeric> #include <ctime> #include <bitset> #include <complex> using namespace std; void solve() { // x是目标值 int n, x; cin >> n >> x; // 字符串s string s; cin >> s; int allb = 0; vector<int> pb = {0}; // 计算前缀和 for (auto t : s) { if (t == '0') allb++; else allb--; pb.push_back(allb); } pb.pop_back(); if (allb == 0) { // 如果发现一个s的前缀和为0,不管多少个s都是为0,只考虑一个s的情况 int c = 0; // 在一个s中查找是否存在结果 for (auto t : pb) { if (t == x) c = 1; } if (c) { // 存在结果,说明是无穷个,因为可以无限叠加s cout << -1 << endl; } else { // 不存在结果,怎么叠加s都没用 cout << 0 << endl; } } else { int ans = 0; // 普通情况,有限的结果 for (int i = 0; i < (int)pb.size(); i++) { // 处理每一个前缀和的情况 int k = (x - pb[i]) / allb; if (x != pb[i] + k * allb) continue; // 如果满足情况,则加1 if (k >= 0) ans++; } cout << ans << endl; } } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); int q; // 用例数量 cin >> q; while (q--) { solve(); } }
C. Obtain The String
You are given two strings ? and ? consisting of lowercase Latin letters. Also you have a string ? which is initially empty. You want string ? to be equal to string ?. You can perform the following operation to achieve this: append any subsequence of ? at the end of string ?. A subsequence is a sequence that can be derived from the given sequence by deleting zero or more elements without changing the order of the remaining elements. For example, if ?=??, ?=?????, you may turn ? into following strings in one operation: 给定字符串s和t,以及空字符串z。每次可以取s的任意一个子序列加到z后面,问至少要取多少次才能让z等价于t。例如z=ac,s=abcde,一次操作可以有如下字符串:
?=????? (if we choose subsequence ???); ?=????? (if we choose subsequence ???); ?=????? (if we choose subsequence ???).
Note that after this operation string ? doesn't change. 注意s不会改变。
Calculate the minimum number of such operations to turn string ? into string ?. 计算最小次数。
Input
The first line contains the integer ? (1≤?≤100) — the number of test cases.
The first line of each testcase contains one string ? (1≤|?|≤105) consisting of lowercase Latin letters.
The second line of each testcase contains one string ? (1≤|?|≤105) consisting of lowercase Latin letters.
It is guaranteed that the total length of all strings ? and ? in the input does not exceed 2⋅105.
Output
For each testcase, print one integer — the minimum number of operations to turn string ? into string ?. If it's impossible print −1.
Example
input 3 aabce ace abacaba aax ty yyt
output 1 -1 3
解题思路:
从字符串s到字符串t,建立一个s的查询表T,依次遍历字符串t,对于每一个字符,查找在表T的位置。这道题精巧之处在于对查询表T的处理,采用二分查找保证了性能。
源代码:C++
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define lowbit(x) ((x) & (-x)) #define inf 0x3f3f3f3f using namespace std; int T; char s[100005], t[100005]; vector<int> num[200]; int main() { scanf("%d", &T); while (T--) { for (int i = 'a'; i <= 'z'; i++) num[i].clear(); scanf("%s", s); scanf("%s", t); // 从s到t // 保存每个字符出现的位置 for (int i = 0; s[i]; i++) num[s[i]].push_back(i); int ans = 1; int nw = -1; for (int i = 0; t[i]; i++) { int x = t[i]; // 不存在这个字符,直接返回-1 if (num[x].size() == 0) { ans = -1; break; } //二分找大于nw的第一个这个字符的位置 int p = upper_bound(num[x].begin(), num[x].end(), nw) - num[x].begin(); if (p == num[x].size()) { //如果已经没法在剩下的位置中取这个字符了,得另起一次从头开始取子序列 ans++; nw = num[x][0]; } else { nw = num[x][p]; } } printf("%dn", ans); } return 0; }

温馨提示
如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注ACM算法日常。
点赞的时候,请宠溺一点