AtCoder Beginner Contest 338
A - Capitalized?
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
void solve()
{
string s;
cin >> s;
int n = s.size();
for (int i = 0; i < n; i++)
{
if (i == 0)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
puts("No");
return;
}
}
else
{
if (s[i] >= 'A' && s[i] <= 'Z')
{
puts("No");
return;
}
}
}
puts("Yes");
}
int main()
{
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
B - Frequency
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
void solve()
{
string s;
cin >> s;
vector<int> cnt(40);
int a = 0;
for (auto c : s)
{
cnt[c - 'a']++;
a = max(a, cnt[c - 'a']);
}
for (int i = 0; i < 30; i++)
{
if (a == cnt[i])
{
char c = i + 'a';
cout << c << endl;
return;
}
}
}
int main()
{
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
C - Leftover Recipes
解题思路:
观察数据范围,选择枚举制造\(A\)菜的数量。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
void solve()
{
int n;
cin >> n;
vector<ll> a(n + 1), b(n + 1), q(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> q[i];
}
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
cin >> b[i];
}
ll ans = 0;
for (int i = 0; i <= 1e6 + 1; i++)
{
vector<ll> t = q;
bool f = true;
for (int j = 1; j <= n; j++)
{
ll cur = i * a[j];
if (cur <= t[j])
{
t[j] -= cur;
}
else
{
f = false;
break;
}
}
if (!f)
{
// cout << i << endl;
break;
}
ll res = 1e18;
for (int j = 1; j <= n; j++)
{
if (b[j] > 0)
{
res = min(res, t[j] / b[j]);
}
}
ans = max(ans, res + i);
}
cout << ans << endl;
}
int main()
{
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
D - Island Tour
解题思路:
从\(a\to b\),一共就两个方向,也就是两种走法。
我们先在环上,计算出最短走法。对于该走法,使用差分数组,记录每条边被经过了多少次,以及经过该边的路径长度总和。
接下来,我们枚举删去边。
如果我们删去改变,意味着,凡是经过改变的路径全部不可走。此时,只能走另一个反向。
假设经过边\(i\)的路径长度之和为\(b[i]\),路径数量为\(c[i]\),则全部路径反走的长度之和为\(n * c[i] - b[i]\)。
因为正反两个走法的长度之和为\(n\)。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
void solve()
{
int n, m;
cin >> n >> m;
vector<ll> a(max(n, m) + 10);
vector<ll> b(max(n, m) + 10), c(max(n, m) + 10);
ll sum = 0;
for (int i = 1; i <= m; i++)
{
cin >> a[i];
if (i > 1)
{
if (a[i] > a[i - 1])
{
int x = a[i] - a[i - 1];
int y = a[i - 1] + n - a[i];
if (x < y)
{
sum += x;
b[a[i - 1]] += x;
b[a[i]] -= x;
c[a[i - 1]] += 1;
c[a[i]] -= 1;
}
else if (x >= y)
{
sum += y;
if (a[i - 1] != 1)
{
b[1] += y;
b[a[i - 1]] -= y;
c[1] += 1;
c[a[i - 1]] -= 1;
}
b[a[i]] += y;
c[a[i]] += 1;
}
}
else
{
int x = a[i - 1] - a[i];
int y = a[i] + n - a[i - 1];
if (x < y)
{
sum += x;
b[a[i]] += x;
b[a[i - 1]] -= x;
c[a[i]] += 1;
c[a[i - 1]] -= 1;
}
else if (x >= y)
{
sum += y;
if (a[i] != 1)
{
b[1] += y;
b[a[i]] -= y;
c[1] += 1;
c[a[i]] -= 1;
}
b[a[i - 1]] += y;
c[a[i - 1]] += 1;
}
}
}
}
ll res = 0;
ll ans = 1e18;
for (int i = 1; i <= n; i++)
{
b[i] += b[i - 1];
c[i] += c[i - 1];
res = c[i] * n - b[i];
ans = min(ans, sum + res - b[i]);
}
cout << ans << endl;
}
int main()
{
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
E - Chords
解题思路:
我们将每条连线表述为\((l,r)\),其中\(l < r\)。
相交条件就是存在一对连线\((l_1,r_1),(l_2,r_2)\),有\(l_1 < l_2 < r_1,r_2 > r_1\)。
所以,我们先排序。
对于第\(i\)条连线,找到所有满足\(l_i <l <r_i\)的连线,然后取区间中最大的\(r\)与\(r_i\)比较,存在符合则存在相交。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
void solve()
{
int n;
cin >> n;
vector<pii> v(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> v[i].fi >> v[i].se;
if (v[i].fi > v[i].se)
{
swap(v[i].fi, v[i].se);
}
}
sort(v.begin() + 1, v.end());
vector<vector<int>> f(n + 10, vector<int>(22));
for (int j = 0; j <= 20; j++)
{
for (int i = 1; i + (1ll << j) - 1 <= n; i++)
{
if (j == 0)
{
f[i][j] = v[i].se;
}
else
{
f[i][j] = max(f[i][j - 1], f[i + (1ll << (j - 1))][j - 1]);
}
}
}
auto get = [&](int l, int r)
{
int len = r - l + 1;
int k = log(len) / log(2);
return max(f[l][k], f[r - (1ll << k) + 1][k]);
};
for (int i = 1; i <= n; i++)
{
auto idx = lower_bound(v.begin() + 1, v.end(), (pii){v[i].se, -1}) - v.begin() - 1;
int l = i + 1;
int r = idx;
if (l > r)
{
continue;
}
ll val = get(l, r);
if (val > v[i].se)
{
puts("Yes");
return;
}
}
puts("No");
}
int main()
{
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
标签:AtCoder,338,Beginner,int,ll,long,solve,using,define
From: https://www.cnblogs.com/value0/p/17991977