Educational Codeforces Round 86 Rated for Div. 2
A. Road To Zero
思路:
贪心,可以肯定的是,先把两个降到一样大所花费的代价使
m
a
x
(
a
,
b
)
−
m
i
n
(
a
,
b
)
max(a,b)-min(a,b)
max(a,b)−min(a,b),然后再进行讨论是单独降,还是一起降
- 单独降的代价: m i n ( a , b ) ∗ 2 ∗ a min(a,b)*2*a min(a,b)∗2∗a
- 一起降的代价: m i n ( a , b ) ∗ b min(a,b)*b min(a,b)∗b
然后选一个最小的就行了
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
typedef vector<int> vi;
typedef long long ll;
typedef pair<int, int> pii;
typedef double db;
int main()
{
int t; cin >> t;
while (t --)
{
int x, y, a, b; cin >> x >> y >> a >> b;
ll ans = 1LL * a * (max(x, y) - min(x, y));
ll q = min(x ,y);
ans += min(q * 2 * a, q * b);
cout << ans << endl;
}
return 0;
}
B. Binary Period
思路
构造一下就好了
- 对于全是0或者全是1组成t,s是它本身就可以了,这样k = 1已经是最小了
- 对于有0又有1的字符串t,寻找一个字符串s,因为 ∣ s ∣ ≥ 2 ∗ ∣ t ∣ |s| \geq 2*|t| ∣s∣≥2∗∣t∣,因此我们可以构造t个“10”串,此时的k=2,也不可能再小,所以也是符合条件的
代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t; cin >> t;
while (t --)
{
string s; cin >> s;
int a = 0;
for (int i = 0; i < s.size(); ++ i)
if(s[i] == '0') a ++;
if(a == 0 || a == s.size()) cout << s << endl;
else
{
for (int i = 0; i < s.size(); ++ i) cout << "10";
cout << endl;
}
}
return 0;
}
C. Yet Another Counting Problem
思路
暴力打个表就可以发现,变化范围是以
l
c
m
(
a
,
b
)
lcm(a,b)
lcm(a,b)为周期的,(lcm(a,b)为a,b的最小公倍数),假设b是较大的那个数,那么变化范围是
[
k
∗
l
c
m
,
k
∗
l
c
m
+
b
)
[k*lcm,k*lcm + b)
[k∗lcm,k∗lcm+b)都是不合法的数据,
[
k
∗
l
c
m
+
b
,
(
k
+
1
)
∗
l
c
m
]
[k*lcm + b, (k + 1)*lcm]
[k∗lcm+b,(k+1)∗lcm]都是合法的数据。
举个例子
a
=
2
,
b
=
3
,
l
c
m
=
6
a = 2, b = 3,lcm = 6
a=2,b=3,lcm=6
n
u
m
=
0
n
u
m
%
2
%
7
=
n
u
m
%
7
%
2
num = 0 \quad num \% 2\%7 =num\%7\%2
num=0num%2%7=num%7%2 不合法
n
u
m
=
1
n
u
m
%
2
%
7
=
n
u
m
%
7
%
2
num = 1 \quad num \% 2\%7 =num\%7\%2
num=1num%2%7=num%7%2 不合法
n
u
m
=
2
n
u
m
%
2
%
7
=
n
u
m
%
7
%
2
num = 2 \quad num \% 2\%7 =num\%7\%2
num=2num%2%7=num%7%2 不合法
n
u
m
=
3
n
u
m
%
2
%
7
≠
n
u
m
%
7
%
2
num = 3 \quad num \% 2\%7 \neq num\%7\%2
num=3num%2%7=num%7%2 合法
n
u
m
=
4
n
u
m
%
2
%
7
≠
n
u
m
%
7
%
2
num = 4 \quad num \% 2\%7 \neq num\%7\%2
num=4num%2%7=num%7%2 合法
n
u
m
=
5
n
u
m
%
2
%
7
≠
n
u
m
%
7
%
2
num = 5 \quad num \% 2\%7 \neq num\%7\%2
num=5num%2%7=num%7%2 合法
接着又是一个新的周期,
n
u
m
=
6
n
u
m
%
2
%
7
=
n
u
m
%
7
%
2
num = 6 \quad num \% 2\%7 =num\%7\%2
num=6num%2%7=num%7%2 不合法
…
因此我们可以很方便的求出前p个有多少个合法的数据,然后前缀和的思想减一下就可得出
[
l
,
r
]
[l,r]
[l,r]之间合法的数据,
注意周期是从0开始的,因此总的数量要+1,
代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
typedef vector<int> vi;
typedef long long ll;
typedef pair<int, int> pii;
typedef double db;
ll lcm;
ll getct (ll p, ll b)
{
p ++;
return p / lcm * (lcm - b) + max(0LL, (p % lcm) - b);
}
int main()
{
int t; cin >> t;
while (t --)
{
ll a, b, q; cin >> a >> b >> q;
if(b < a) swap(a, b);
lcm = a * b / __gcd(a ,b);
while (q --)
{
ll l, r; cin >> l >> r;
cout << getct(r, b) - getct(l - 1, b) << endl;
}
}
return 0;
}