Codeforces Round 898 (Div. 4)
A. Short Sort
解题思路:
遍历所有交换情况,看是否有\(abc\).
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
string s;
cin >> s;
string a = s;
swap(a[0], a[1]);
string b = s;
swap(b[0], b[2]);
string c = s;
swap(c[1], c[2]);
string t = "abc";
if (s == t || a == t || b == t || c == t)
{
puts("YES");
}
else
{
puts("NO");
}
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
B. Good Kid
解题思路:
将最小的数字加一.
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
scanf("%d", &n);
vector<int> a(n + 1);
int idx = 0;
int res = 12312;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
if (a[i] < res)
{
res = a[i];
idx = i;
}
}
a[idx]++;
ll ans = 1;
for (int i = 1; i <= n; i++)
{
ans *= (ll)a[i];
}
printf("%lld\n", ans);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
C. Target Practice
解题思路:
由于图是固定的,暴力判断每个击中的点属于哪一类即可。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
char g[100][100];
void solve()
{
for (int i = 1; i <= 10; i++)
{
scanf("%s", g[i] + 1);
}
n = 10;
ll ans = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (g[i][j] == 'X')
{
if (i == 1 || i == 10)
{
ans += 1;
}
else if (i == 2 || i == 9)
{
if (j == 1 || j == 10)
{
ans += 1;
}
else
{
ans += 2;
}
}
else if (i == 3 || i == 8)
{
if (j == 1 || j == 10)
{
ans += 1;
}
else if (j == 2 || j == 9)
{
ans += 2;
}
else
{
ans += 3;
}
}
else if (i == 4 || i == 7)
{
if (j == 1 || j == 10)
{
ans += 1;
}
else if (j == 2 || j == 9)
{
ans += 2;
}
else if (j == 3 || j == 8)
{
ans += 3;
}
else
{
ans += 4;
}
}
else if (i == 5 || i == 6)
{
if (j == 1 || j == 10)
{
ans += 1;
}
else if (j == 2 || j == 9)
{
ans += 2;
}
else if (j == 3 || j == 8)
{
ans += 3;
}
else if (j == 4 || j == 7)
{
ans += 4;
}
else
{
ans += 5;
}
}
}
}
}
printf("%lld\n", ans);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
D. 1D Eraser
解题思路:
从左往右遍历,遇到一个\(B\)就以他为起点向右染白即可。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
scanf("%d %d", &n, &k);
string s;
cin >> s;
int cnt = 0;
for (int i = 0; i < n; i++)
{
if (s[i] == 'B')
{
cnt++;
int j = 0;
for (j = i; j <= i + k - 1; j++)
{
s[i] = 'W';
}
j--;
i = j;
}
}
printf("%d\n", cnt);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
E. Building an Aquarium
解题思路:
二分高度,暴力判断。
注意本题二分边界,最小取到1。
由于答案上界为\(2\times 10^9\),\(n = 1,a[1] = 10^9,x = 10^9\)。
右边界也别取太大,如\(10^{18}\),二分过程会爆\(long \ long\)。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
scanf("%d %d", &n, &k);
vector<ll> a(n + 1);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
}
ll l = 1;
ll r = 3e9;
auto check = [&](ll h)
{
ll sum = 0;
for (int i = 1; i <= n; i++)
{
sum += max(0ll, h - a[i]);
}
if (sum > k)
{
return false;
}
else
{
return true;
}
};
while (l + 1 < r)
{
ll mid = l + r >> 1;
if (check(mid))
{
l = mid;
}
else
{
r = mid;
}
}
printf("%lld\n", l);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
F. Money Trees
解题思路:
类似滑动窗口。
从左往右遍历,在线记录以\(i\)为最后一个元素,向左最长可以选择多少元素。
用前缀和计算当前最大区间和。
若区间和大于限制,那么从左端点开始一个个删去,直至区间和合法。此时区间长度就是以第\(i\)个元素为结尾的最长区间。
全局答案就是所有最长区间中的最大值。
注意:左右端点可以相等。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
scanf("%d %d", &n, &k);
vector<int> a(n + 1), h(n + 1), b(n + 1);
vector<ll> s(n + 1);
vector<pii> v;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
s[i] = a[i] + s[i - 1];
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &h[i]);
}
ll ans = 0;
int idx = 0;
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
b[i] = 0;
}
else if (h[i - 1] % h[i] == 0)
{
b[i] = b[i - 1] + 1;
}
else
{
b[i] = 0;
// continue;
}
int l = max(i - b[i], idx);
int r = i;
ll res = s[r] - s[l - 1];
if (res <= k)
{
// cout << i << ' ' << (r - l + 1) << endl;
ans = max(ans, r - l + 1ll);
}
else
{
while (res > k)
{
res -= a[l];
l++;
}
idx = l;
ans = max(ans, r - l + 1ll);
}
}
printf("%lld\n", ans);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
G .ABBC or BACB
解题思路:
我们可以将连续的\(A\)看成\(A\)块。
我们发现,一个\(B\)无论在\(A\)块的左边还是右边,都可以对整个\(A\)块进行连续操作,此时对答案的贡献就是块中\(A\)的个数\(res\)。
所以,我们统计\(A\)块的数量\(cnt_a\),同时统计与\(A\)块相邻的\(B\)的数量\(cnt_b\)。
如果\(cnt_b >= cnt_a\),那么答案就是\(res\).
否则,答案就是\(res-最小的A块中的A的数量\)。因为\(A\)块就是由\(B\)分割而来,\(min(cnt_b) = cnt_a - 1\)。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
string s;
cin >> s;
n = s.size();
s = ' ' + s;
int ans = 0;
int cnt = 0;
int res = 0;
vector<int> v;
for (int i = 1; i <= n; i++)
{
char c = s[i];
if (c == 'A')
{
cnt++;
}
else
{
if (s[i - 1] == 'A' || s[i + 1] == 'A')
{
res++;
}
if (cnt)
{
v.push_back(cnt);
ans += cnt;
}
cnt = 0;
}
}
if (cnt)
{
v.push_back(cnt);
ans += cnt;
}
sort(v.begin(), v.end());
if (res < v.size())
{
if (!v.empty())
{
ans -= v[0];
}
}
printf("%d\n", ans);
}
int main()
{
int t = 1;
scanf("%d", &t);
while (t--)
{
solve();
}
return 0;
}
标签:10,const,898,Codeforces,long,int,using,Div,define
From: https://www.cnblogs.com/value0/p/17722172.html