A. Only Pluses
分析:一开始写麻烦了,用的if枚举,写了好长一段,打完后看的别人代码,用的三个for来进行枚举,然后取最大值,这样更简洁一些
#include <iostream>
using namespace std;
void solve()
{
int a, b, c;
cin >> a >> b >> c;
int res = 0;
for(int i = 0; i <= 5; i++)
{
for(int j = 0; j <= 5 - i; j++)
{
for(int k = 0; k <= 5 - i - j; k++)
{
res = max(res, (a+i)*(b+j)*(c+k));
}
}
}
cout << res << endl;
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
B. Angry Monk
分析:根据样例我们自己在纸上比划一下,我们会发现,需要把除了最大值的数据全部拆分为1,然后再进行合并,只有这样才能保证合并为n。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int a[N];
void solve()
{
long long ans = 0;
int n, k;
cin >> n >> k;
for(int i = 0; i < k; i++) cin >> a[i];
sort(a, a+k);
for(int i = 0; i < k-1; i++)
{
//拆分需要a[i]-1次操作,合并需要a[i]次操作
if(a[i] != 1) ans += a[i]-1+a[i];
else ans += 1;
}
cout << ans << endl;
for(int i = 0; i < k; i++) a[i] = 0;
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
C. Gorilla and Permutation
分析:g(i)是长度为i的前缀中数值不大于m的数字的全部的和,f(i)是长度为i的前缀中数值不小于k的数字的和,求 ∑ i = 1 n f ( i ) \sum_{i=1}^{n}f(i) ∑i=1nf(i)+ ∑ i = 1 n g ( i ) \sum_{i=1}^{n}g(i) ∑i=1ng(i)的值,我们只需要保证前一项尽可能的大,后一项尽可能地小就可以了,要这样构造的话,我们需要让满足f(i)条件的大数在最靠前,小数在后;对于满足g(i)条件的数,我们需要让小数尽可能在前,大数尽可能在后,因为越靠前满足条件的数,被加的次数会越多,代码如下:
#include <iostream>
using namespace std;
void solve()
{
int n, m, k;
cin >> n >> m >> k;
for(int i = n; i >= 1; i--)
{
if(i <= m)
{
break;
}
else
{
cout << i << ' ';
}
}
for(int i = 1; i <= m; i++) cout << i << ' ';
cout << endl;
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
D. Test of Love
分析:赛事想到了DP但没写出来/(ㄒoㄒ)/~~,当恩科尔在第i
个位置时,枚举他的跳跃范围j
,看能不能从i-j
的位置处转移过来,并且如果i-1
这个格子为W,则还要再考虑从i-1
游过来的情况,代码如下:
#include <iostream>
using namespace std;
const int N = 2e5+10;
int dp[N];
void solve()
{
int n, m, k;
cin >> n >> m >> k;
string s;
cin >> s;
//岸就相当于原木
s = 'L' + s + 'L';
for(int i = 1; i <= n+1; i++) dp[i] = 1e9;
for(int i = 1; i <= n+1; i++)
{
for(int j = 1; j <= min(i, m); j++)
{
if(i-j >= 0 && s[i-j] == 'L')
dp[i] = min(dp[i], dp[i-j]);
}
if(s[i-1] == 'W') dp[i] = min(dp[i], dp[i-1]+1);
}
if(dp[n+1] <= k) puts("Yes");
else puts("No");
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}
E. Novice’s Mistake
解释在代码中,代码如下:
#include <iostream>
#include <vector>
using namespace std;
int Num(int x)
{
int res = 0;
while(x)
{
res++;
x/=10;
}
return res;
}
void solve()
{
int n;
cin >> n;
vector<pair<int, int>> v;
//获得n的位数
int d = Num(n);
//a代表多少个字符串拼接
for(int a = 1; a <= 10000; a++)
{
//去除b个,转化为取前i个
//因为字符串最多6位,所以剩下的字符范围为取6位和此字符串的位数中的最小值
for(int i = 1; i <= min(6, a*d); i++)
{
string s = to_string(n);
//获得前i个数字
while(s.size() < i) s += s;
while(s.size() > i) s.pop_back();
//将字符串转化为整数
int m = stoll(s);
//a*d-i就是b,b要大于1
if(m == a*n - (a*d-i) && a*d - i >= 1)
{
v.push_back({a, a*d-i});
}
}
}
cout << v.size() << endl;
for(auto x : v)
{
cout << x.first << ' ' << x.second << endl;
}
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
return 0;
}