T1 chip change
题目描述
奶牛 Bessie 手里有 A 个 A 类筹码,以及 B 个 B 类筹码(0 ≤ A , B ≤ 10 9 0\le A,B\le 10^9 0 ≤ A , B ≤ 1 0 9 )。
她可以进行如下操作任意多次:
如果当前 至少有 c B c_B c B 个 B 类筹码,就可以用 c B c_B c B 个 B 类筹码 兑换 c A c_A c A 个 A 类筹码。
其中 1 ≤ c A , c B ≤ 10 9 1\le c_A,c_B\le 10^9 1 ≤ c A , c B ≤ 1 0 9 。
现在问:最小的非负整数 x x x 是多少,使得满足下面的“保证”条件:
在 Bessie 额外收到 x x x 个随机筹码之后(每个筹码可能是 A 类或 B 类,分配方式未知),无论这 x x x 个筹码具体怎么分配成 A/B ,Bessie 都一定能通过若干次兑换操作,使得最终拥有的 A 类筹码数量 至少为 f A f_A f A (0 ≤ f A ≤ 10 9 0\le f_A\le 10^9 0 ≤ f A ≤ 1 0 9 )。
你需要对每个测试用例输出这个最小的 x x x 。
输入格式
第一行是整数 T T T ,表示测试用例个数(1 ≤ T ≤ 10 4 1\le T\le 10^4 1 ≤ T ≤ 1 0 4 )。
接下来 T T T 行,每行包含 5 个整数:
A , B , c A , c B , f A A,\ B,\ c_A,\ c_B,\ f_A
A , B , c A , c B , f A
输出格式
对每个测试用例输出一行一个整数:对应的答案 x x x 。
注意:数据范围很大,可能需要 64 位整数类型(例如 C/C++ 的 long long)。
样例
样例输入1:
2
2 3 1 1 6
2 3 1 1 4
样例输出1:
1
0
样例输入1:
5
0 0 2 3 5
0 1 2 3 5
1 0 2 3 5
10 10 2 3 5
0 0 1 1000000000 1000000000
样例输出2:
9
8
7
0
1000000000000000000
并解释(原文意思):
第 1 组(A = B = 0 , c A = 2 , c B = 3 , f A = 5 A=B=0,c_A=2,c_B=3,f_A=5 A = B = 0 , c A = 2 , c B = 3 , f A = 5 ):
Bessie 一开始没有筹码。只要她额外收到任意 9 个筹码,不管这 9 个里 A/B 怎么分配,她都能通过兑换最终得到至少 5 个 A。
比如她收到 2 个 A 和 7 个 B,可以兑换两次得到 6 个 A(≥ 5 \ge 5 ≥ 5 )。
但如果只收到 8 个 B,则最多兑换 2 次得到 4 个 A(<5),所以 8 不够。
第 4 组:她一开始就已经有足够多的 A,因此答案是 0。
评分提示
输入 3:c A = c B = 1 c_A=c_B=1 c A = c B = 1
输入 4-5:所有用例的 x ≤ 10 x\le 10 x ≤ 10
输入 6-7:c A = 2 , c B = 3 c_A=2, c_B=3 c A = 2 , c B = 3
输入 8-12:无额外限制
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
ll a, b, ca, cb, fa;
i128 cal(ll y, ll tot) {
return (i128)tot - y + ((i128)y / cb) * ca;
}
bool chk(ll x) {
ll tot = a + b + x;
ll lim = b + x;
i128 mn = cal(lim, tot);
ll tg = cb - 1;
if (ca > cb) {
ll r = b % cb;
ll d = (tg - r + cb) % cb;
ll y = b + d;
if (y <= lim) mn = min(mn, cal(y, tot));
} else {
ll r = lim % cb;
ll d = (r - tg + cb) % cb;
ll y = lim - d;
if (y >= b) mn = min(mn, cal(y, tot));
}
return mn >= fa;
}
void sol() {
cin >> a >> b >> ca >> cb >> fa;
ll l = 0, r = 2e18, ans = 2e18;
while (l <= r) {
ll md = l + (r - l) / 2;
if (chk(md)) {
ans = md;
r = md - 1;
} else {
l = md + 1;
}
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
sol();
}
return 0;
}
T2 COW
题目描述
Bessie 得到一个正整数 N N N 和一个长度为 3 N 3N 3 N 的字符串 S S S 。
字符串 S S S 的生成方式如下:把 N N N 个长度为 3 的字符串拼接起来,而每个长度为 3 的字符串都是 "COW" 的一个循环移位(cyclic shift),也就是说每段只能是下面三种之一:
平方串(square string)
字符串 X X X 被称为 平方串 ,当且仅当存在某个字符串 Y Y Y ,使得:
X = Y + Y X = Y + Y
X = Y + Y
其中 + + + 表示字符串拼接。
例如:
操作
一次操作中,Bessie 可以从 S S S 中删除任意一个子序列 T T T ,要求 T T T 是一个平方串。
子序列 指:从原串中删除若干个字符(可以删除 0 个),保持剩余字符的相对顺序得到的字符串。
目标
你需要判断:是否可以通过若干次操作,把 S S S 变成空串 。
如果可以,还要输出一种删除方案。
参数 k k k 与操作次数要求
题目还给一个参数 k ∈ { 0 , 1 } k\in\{0,1\} k ∈ { 0 , 1 } 。
设你输出的方案使用了 M M M 次操作。
若 k = 0 k=0 k = 0 :必须保证 M M M 等于最少可能操作次数 (最优)。
若 k = 1 k=1 k = 1 :允许 M M M 最多为 最少操作次数 + 1 (几乎最优,多一次也行)。
输入格式
第一行包含两个整数:
T T T :测试组数(1 ≤ T ≤ 10 4 1\le T\le 10^4 1 ≤ T ≤ 1 0 4 )
k k k :参数(0 ≤ k ≤ 1 0\le k\le 1 0 ≤ k ≤ 1 )
每个测试用例包含:
一行整数 N N N (1 ≤ N ≤ 10 5 1\le N\le 10^5 1 ≤ N ≤ 1 0 5 )
一行字符串 S S S ,长度为 3 N 3N 3 N
保证所有测试中 N N N 的总和不超过 10 5 10^5 1 0 5 。
输出格式
对每个测试用例,按如下方式输出:
如果无法把 S S S 变成空串:输出一行 -1
否则:
样例
样例输入1
3 1
3
COWOWCWCO
4
WCOCOWWCOCOW
6
COWCOWOWCOWCOWCOWC
样例输出1
-1
1
1 1 1 1 1 1 1 1 1 1 1 1
3
3 3 2 3 3 2 1 1 1 1 1 1 1 1 1 1 1 1
样例解释1
对于最后一个测试用例,最优(最少)操作次数是 2 ,因此当 k = 1 k=1 k = 1 时,只要你的构造满足 M = 2 M=2 M = 2 或 M = 3 M=3 M = 3 都会被判正确(允许比最优多 1 次)。
如果取 M = 3 M=3 M = 3 ,下面给出一种可行方案:
第一次操作:删除最后 12 个字符。此时剩下字符串为 COWCOW。
第二次操作:删除子序列 WW。此时剩下字符串为 COCO。
第三次操作:删除所有剩余字符。最终变成空串。
T1 chip change
题目描述
奶牛 Bessie 手里有 A 个 A 类筹码,以及 B 个 B 类筹码(0 ≤ A , B ≤ 10 9 0\le A,B\le 10^9 0 ≤ A , B ≤ 1 0 9 )。
她可以进行如下操作任意多次:
如果当前 至少有 c B c_B c B 个 B 类筹码,就可以用 c B c_B c B 个 B 类筹码 兑换 c A c_A c A 个 A 类筹码。
其中 1 ≤ c A , c B ≤ 10 9 1\le c_A,c_B\le 10^9 1 ≤ c A , c B ≤ 1 0 9 。
现在问:最小的非负整数 x x x 是多少,使得满足下面的“保证”条件:
在 Bessie 额外收到 x x x 个随机筹码之后(每个筹码可能是 A 类或 B 类,分配方式未知),无论这 x x x 个筹码具体怎么分配成 A/B ,Bessie 都一定能通过若干次兑换操作,使得最终拥有的 A 类筹码数量 至少为 f A f_A f A (0 ≤ f A ≤ 10 9 0\le f_A\le 10^9 0 ≤ f A ≤ 1 0 9 )。
你需要对每个测试用例输出这个最小的 x x x 。
输入格式
第一行是整数 T T T ,表示测试用例个数(1 ≤ T ≤ 10 4 1\le T\le 10^4 1 ≤ T ≤ 1 0 4 )。
接下来 T T T 行,每行包含 5 个整数:
A , B , c A , c B , f A A,\ B,\ c_A,\ c_B,\ f_A
A , B , c A , c B , f A
输出格式
对每个测试用例输出一行一个整数:对应的答案 x x x 。
注意:数据范围很大,可能需要 64 位整数类型(例如 C/C++ 的 long long)。
样例
样例输入1:
2
2 3 1 1 6
2 3 1 1 4
样例输出1:
1
0
样例输入1:
5
0 0 2 3 5
0 1 2 3 5
1 0 2 3 5
10 10 2 3 5
0 0 1 1000000000 1000000000
样例输出2:
9
8
7
0
1000000000000000000
并解释(原文意思):
第 1 组(A = B = 0 , c A = 2 , c B = 3 , f A = 5 A=B=0,c_A=2,c_B=3,f_A=5 A = B = 0 , c A = 2 , c B = 3 , f A = 5 ):
Bessie 一开始没有筹码。只要她额外收到任意 9 个筹码,不管这 9 个里 A/B 怎么分配,她都能通过兑换最终得到至少 5 个 A。
比如她收到 2 个 A 和 7 个 B,可以兑换两次得到 6 个 A(≥ 5 \ge 5 ≥ 5 )。
但如果只收到 8 个 B,则最多兑换 2 次得到 4 个 A(<5),所以 8 不够。
第 4 组:她一开始就已经有足够多的 A,因此答案是 0。
评分提示
输入 3:c A = c B = 1 c_A=c_B=1 c A = c B = 1
输入 4-5:所有用例的 x ≤ 10 x\le 10 x ≤ 10
输入 6-7:c A = 2 , c B = 3 c_A=2, c_B=3 c A = 2 , c B = 3
输入 8-12:无额外限制
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
ll a, b, ca, cb, fa;
i128 cal(ll y, ll tot) {
return (i128)tot - y + ((i128)y / cb) * ca;
}
bool chk(ll x) {
ll tot = a + b + x;
ll lim = b + x;
i128 mn = cal(lim, tot);
ll tg = cb - 1;
if (ca > cb) {
ll r = b % cb;
ll d = (tg - r + cb) % cb;
ll y = b + d;
if (y <= lim) mn = min(mn, cal(y, tot));
} else {
ll r = lim % cb;
ll d = (r - tg + cb) % cb;
ll y = lim - d;
if (y >= b) mn = min(mn, cal(y, tot));
}
return mn >= fa;
}
void sol() {
cin >> a >> b >> ca >> cb >> fa;
ll l = 0, r = 2e18, ans = 2e18;
while (l <= r) {
ll md = l + (r - l) / 2;
if (chk(md)) {
ans = md;
r = md - 1;
} else {
l = md + 1;
}
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
sol();
}
return 0;
}
T2 COW
题目描述
Bessie 得到一个正整数 N N N 和一个长度为 3 N 3N 3 N 的字符串 S S S 。
字符串 S S S 的生成方式如下:把 N N N 个长度为 3 的字符串拼接起来,而每个长度为 3 的字符串都是 "COW" 的一个循环移位(cyclic shift),也就是说每段只能是下面三种之一:
平方串(square string)
字符串 X X X 被称为 平方串 ,当且仅当存在某个字符串 Y Y Y ,使得:
X = Y + Y X = Y + Y
X = Y + Y
其中 + + + 表示字符串拼接。
例如:
操作
一次操作中,Bessie 可以从 S S S 中删除任意一个子序列 T T T ,要求 T T T 是一个平方串。
子序列 指:从原串中删除若干个字符(可以删除 0 个),保持剩余字符的相对顺序得到的字符串。
目标
你需要判断:是否可以通过若干次操作,把 S S S 变成空串 。
如果可以,还要输出一种删除方案。
参数 k k k 与操作次数要求
题目还给一个参数 k ∈ { 0 , 1 } k\in\{0,1\} k ∈ { 0 , 1 } 。
设你输出的方案使用了 M M M 次操作。
若 k = 0 k=0 k = 0 :必须保证 M M M 等于最少可能操作次数 (最优)。
若 k = 1 k=1 k = 1 :允许 M M M 最多为 最少操作次数 + 1 (几乎最优,多一次也行)。
输入格式
第一行包含两个整数:
T T T :测试组数(1 ≤ T ≤ 10 4 1\le T\le 10^4 1 ≤ T ≤ 1 0 4 )
k k k :参数(0 ≤ k ≤ 1 0\le k\le 1 0 ≤ k ≤ 1 )
每个测试用例包含:
一行整数 N N N (1 ≤ N ≤ 10 5 1\le N\le 10^5 1 ≤ N ≤ 1 0 5 )
一行字符串 S S S ,长度为 3 N 3N 3 N
保证所有测试中 N N N 的总和不超过 10 5 10^5 1 0 5 。
输出格式
对每个测试用例,按如下方式输出:
如果无法把 S S S 变成空串:输出一行 -1
否则:
样例
样例输入1
3 1
3
COWOWCWCO
4
WCOCOWWCOCOW
6
COWCOWOWCOWCOWCOWC
样例输出1
-1
1
1 1 1 1 1 1 1 1 1 1 1 1
3
3 3 2 3 3 2 1 1 1 1 1 1 1 1 1 1 1 1
样例解释1
对于最后一个测试用例,最优(最少)操作次数是 2 ,因此当 k = 1 k=1 k = 1 时,只要你的构造满足 M = 2 M=2 M = 2 或 M = 3 M=3 M = 3 都会被判正确(允许比最优多 1 次)。
如果取 M = 3 M=3 M = 3 ,下面给出一种可行方案:
第一次操作:删除最后 12 个字符。此时剩下字符串为 COWCOW。
第二次操作:删除子序列 WW。此时剩下字符串为 COCO。
第三次操作:删除所有剩余字符。最终变成空串。