Educational Codeforces Round 146 (Rated for Div. 2)
A. Coins
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve() {
int n = read() , k = read();
if( n % 2 == 0 ) printf("YES\n");
else if( k & 1 ) printf("YES\n");
else printf("NO\n");
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
B. Long Legs
枚举\(m\),\(m\)确定了答案是$m-1+\left \lceil \frac x m \right \rceil + \left \lceil \frac y m \right \rceil $
至于枚举的范围,感觉是玄学,大家随便搞的都能过
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve() {
int x = read(), y = read() , res = x + y;
for( int i = 1 , n = sqrt(x) + sqrt(y) + 2 ; i <= n ; i ++ )
res = min( res , ( x + i - 1 ) / i + ( y + i - 1 ) / i + i - 1 );
cout << res << "\n";
}
int32_t main() {
for (int t = read(); t; t--)
solve();
return 0;
}
C. Search in Parallel
访问次数越多的放的位置越靠前,所以直接贪心一下就好了
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve() {
int n = read(), s1 = read(), s2 = read(), t1 = s1, t2 = s2;
vector<pair<int, int>> p;
vector<int> a, b;
for (int i = 1, x; i <= n; i++)
x = read(), p.emplace_back(x, i);
sort(p.begin(), p.end(), greater<pair<int, int>>());
for( auto [ w , i ] : p ){
if( t1 < t2 ) a.push_back(i) , t1 += s1;
else b.push_back(i) ,t2 += s2;
}
printf("%lld" , a.size() );
for( auto i : a ) printf(" %lld", i );
printf("\n%lld" , b.size() );
for( auto i : b ) printf(" %lld", i );
printf("\n");
return;
}
int32_t main() {
for (int t = read(); t; t--)
solve();
return 0;
}
D. Balancing Weapons
枚举一下上届\(r\),然后算一下下届\(r-k\),然后二分查找一下有多少个\(p_i\)在\([r-k,r]\)之间,在区间之外都都是要操作的。
现在其实就是要看区间外的能否通过操作移动进来,首先如果\(f_i \le k+1\)就一定可以移动进进一个宽度为\(k\)的区间,否则就要看是否满足\(\left \lfloor \frac{r}{f} \right \rfloor f \ge r-k\),这个式子可以化成\(k \ge r - \left \lfloor \frac{r}{f} \right \rfloor f = r \mod f\)。其实不难想出已经在区间内的\(p_i\)也是满足刚才的条件。所以只要判断一下所有的\(f\)时候满足即可,不用区分是区间内对应的还是区间外对应的。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int calc(vector<int> &a, int l, int r) {
return upper_bound(a.begin(), a.end(), r) -
lower_bound(a.begin(), a.end(), l);
}
void solve() {
int n = read(), k = read();
vector<int> f(n), d(n), a(n);
for (auto &i: f) i = read();
for (auto &i: d) i = read();
for (int i = 0; i < n; i++) a[i] = f[i] * d[i];
sort(f.begin(), f.end());
f.resize(unique(f.begin(), f.end()) - f.begin());
reverse(f.begin(), f.end());
while (f.size() && f.back() <= k + 1) f.pop_back();
sort(a.begin(), a.end());
int res = n, r = k + 1;
for (auto v: a) {
for (r = max(v, r); r <= v + k; r++) {
bool flag = true;
for (auto u: f)
if (r % u > k) {
flag = false;
break;
}
if (flag) res = min(res, n - calc(a, r - k, r));
}
}
cout << res << "\n";
return;
}
int32_t main() {
for (int t = read(); t; t--)
solve();
return 0;
}