J. Strange Sum
思路:总而言之,就是最多可以取两个元素,因此,排序一遍数组 a a a,然后对比一下 m a x ( 0 , a n − 1 , a n − 1 + a n − 2 ) max(0,a_{n - 1},a_{n - 1} + a_{n - 2}) max(0,an−1,an−1+an−2)即可得出答案。
void solve()
{
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
cout << max({ 0, a[n - 1], a[n - 1] + a[n - 2] });
}
看到可以选可以不选,最小值可以为 0 0 0了,他可能只有一个正的数,所以有可能只选最大的一个,然后看到任意区间,一定长度,可以选排好序的数组的最后两个数和最后一个数与 0 0 0 对比大小即可。
F. Hotel
思路:模拟实现。无论性别不同,双人间和单人间都有两种方案,都选双人间或者都选单人间
。
void solve()
{
int n, c1, c2;
cin >> n >> c1 >> c2;
ll sum = 0;
while (n--)
{
string s;
cin >> s;
sort(s.begin(), s.end());
if (s[0] == s[1] || s[1] == s[2])
{
sum += min(c1, c2) + min(c1 * 2, c2);
}
else
{
sum += min(c1, c2) * 3;
}
}
cout << sum << endl;
}
C. Clone Ranran
思路:显然,先克隆再出题方案最佳。
void solve()
{
ll a, b, c;
cin >> a >> b >> c;
ll ans = 1e18;
for (int i = 1; i <= 31; i++) {
ll m = ksm(2, i - 1);
ll sum = (i - 1) * a;
sum += c / m * b + (c % m != 0) * b;
ans = min(ans, sum);
}
cout << ans << endl;
}
G. Perfect Word
思路:看数据范围,不超过 1 e 5 1e5 1e5,平均每个字符串的长度为 350 350 350 左右,可以暴力。所以这题采取暴力的方式。只要这个字符串所有的子串都存在,这就是个完美的字符串,我们对这些完美字符串取最长即可
void solve()
{
int n; cin >> n;
map<string, int> mp;
for (int i = 0; i < n; i++) {
cin >> s[i];
mp[s[i]] ++;
}
ll res = 0;
for (int i = 0; i < n; i++) {
string str = s[i];
int sz = str.size();
int flag = 1;
for (int l = 0; l < sz; l++) {
for (int r = l + 1; r <= sz; r++) {
string Ms = str.substr(l, r);
if (!mp[Ms]) {
flag = 0;
break;
}
}
if (!flag) {
break;
}
}
if (flag) {
res = max(res, 1ll * sz);
}
}
cout << res << endl;
}
E. Find Maximum
思路:首先,我们打表,发现答案不是很大,因此考虑规律。经观察发现,每一个 f i f_i fi 的值等于 i i i 的三进制的位数和每一位的值相加, 12 ( 10 ) = = 110 ( 3 ) , f [ 12 ] = 2 + 3 = 5 12(10) == 110(3),f[12] = 2 + 3 = 5 12(10)==110(3),f[12]=2+3=5。显然,在一定的位数下,让每一位尽可能的出现 2 2 2 的情况是最优的。因此我们考虑几种情况
1. 1. 1. f [ l ] f[l] f[l] 是有可能大于 f [ r ] f[r] f[r]的
2. 2. 2. 尽可能的造出合法的最优解,在每一位不是 0 0 0 上退位,后面的位数全部为 2 2 2 的合法性就有了
vector<int> get(ll x,int u)
{//进制转换
vector<int> a;
while(x){
int t = x % u;
a.push_back(t);
x /= u;
}
reverse(a.begin(),a.end());
return a;
}
ll query(ll x)
{
if(x == 0) return 1;
else if(x % 3 == 0) return query(x / 3) + 1;
else return query(x - 1) + 1;
}
void solve()
{
ll l,r;
cin >> l >> r;
vector<int> vec = get(r,3);
ll ans = max(query(l),query(r));
int sz = vec.size();
//cout << query(l) << ' ' << query(r);
for(int i = 0; i < sz; i ++){
if(vec[i] == 0) continue;
ll sum = 0;
for(int j = 0; j < i; j ++){
sum = sum * 3 + vec[j];
}
sum = sum * 3 + vec[i] - 1;//始终在r之下
for(int j = i + 1; j < sz; j ++){
sum = sum * 3 + 2;
}
if(sum >= l && sum <= r){//造的可能小于l
ans = max(ans,query(sum));
}
}
cout << ans << endl;
}