Codeforces Round 1006 (Div. 3)(部分题解)
A. New World, New Me, New Array
思路:这题挺简单的,在对k取绝对值后会更简单一点。
然后注意上取整。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n, k, p;
cin >> n >> k >> p;
k = abs(k);
if (n*p < k) cout << -1 << endl;
else {
cout << (k+p-1)/p << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B. Having Been a Treasurer in the Past, I Help Goblins Deceive
思路:统计‘-’和‘_’的数量,‘-’会分在‘_’的两边,保证左右乘积最大,即尽可能平均分配。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n;
string s;
cin >> n;
cin >> s;
int n1 = count(s.begin(), s.end(), '-');
int n2 = n-n1;
if (n1 < 2 || n2 < 1) cout << 0 << endl;
else {
int cnt = n1/2;
cout << cnt*(n1-cnt)*n2 << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C. Creating Keys for StORages Has Become My Main Skill
思路:我看了半天才看懂MEX(S)的意思,这里补充介绍一下,就是它的值为0到后第一个没在S集合里面的值,因此它的最大值不会超过n-1,所以我们要让它最大,就要从0开始枚举。这里代码(i&x)==i表示i的二进制数都包含在x中,一旦枚举到不满足,MEX值定了,所以我们可以为任何(i&x)==i的i值,显然0必定符合且简单,所以不满足就输出0,当枚举到最后一个数时,我们还要考虑前面所有的OR是否等于x,这里我们考虑到如果加上次i=n-1满足也可以输出该i,不满足我们就要输出一个能让其满足的数,即(num^x)可以帮缺少的二进制1都补上。(二进制)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n, x;
cin >> n >> x;
int num = 0;
for (int i = 0; i<n; i++){
if (i == n-1){
if ((i|num) == x){
cout << i << endl;
}
else cout << (num^x) << endl;
return ;
}
if ((i&x)==i){
cout << i << " ";
num |= i;
}
else{
cout << 0 << " ";
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D. For Wizards, the Exam Is Easy, but I Couldn't Handle It
思路:这道题由于n的范围比较小,可以直接暴力做出来,对于一个位置,往后枚举比较。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i<n; i++) cin >> a[i];
int sum = 0;
for (int i = 0; i<n; i++){
for (int j = i+1; j<n; j++){
sum += (a[i] > a[j]?1:0);
}
}
int l = 0, r = 0;
int ans = sum;
for (int i = 0; i<n; i++){
int cur = sum;
for (int j = i+1; j<n; j++){
cur -= (a[i] > a[j]?1:0);
cur += (a[i] < a[j]?1:0);
if (cur < ans){
ans = cur;
l = i;
r = j;
}
}
}
cout << l+1 << " " << r+1 << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. Do You Love Your Hero and His Two-Hit Multi-Target Attacks?
思路:首先看到有公式之类要想着化简或者转化,这里对公式化简为
所以只要x轴相等或者y轴相等就可以为一对,我们可以指定一个轴,然后来满足此条件。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
void solve()
{
int k;
cin >> k;
vector<array<int, 2>> ans;
int x = 0, y = 0;
while (k){
x++;
int s = 1;
while (s*(s+1)/2 <= k) s++;
k -= s*(s-1)/2;
for (int i = 1; i<=s; i++){
y++;
ans.push_back({x, y});
}
}
cout << ans.size() << endl;
for (auto [x, y]:ans){
cout << x << " " << y << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}