A. Painting the Ribbon
题意:n个物体,m个颜色,alice要给每个物体任意涂一个颜色。bob可以给k个物体涂色 ,问alice能否阻止bob让所有的物体颜色都相同。
思路:思维题。如果m=1,那么无解。如果m > 1,那么bob如果想要染成同一个颜色,alice可以让bob需要染色的数量最多。如果染色的数量最多,那么m个颜色都要用上,其中颜色最多的part一定是(n - m + 1) / m,这个颜色也就是bob的目标色。 那么bob要染色的数量就是n - (n - m + 1) / m,如果k >= 这个数,那么alice就失败,否则成功。
总结:太久没写cf的题了,想了好久。cf果然是锻炼思维的绝境之地。
void solve(){
int n, m, k;
cin >> n >> m >> k;
if (k >= n - (n + m - 1) / m){
cout << "NO\n";
}
else{
cout << "YES\n";
}
}
B. Make It Ugly
题意:一个数组是beautiful的,如果他能够通过这个操作将数组所有的数字变成相同的。 if (a[i - 1] == a[i + 1]) a[i] = a[i - 1];
问:最少删除多少个数字,可以让这个数组不是beautiful的。
思路:依然是思维题,很容易想到如果首末不相等或者所有元素都相等,那么不需要操作。而且需要操作的元素一定跟首元素不相等,我们的目的是让需要操作的元素作为最后一个元素出现,或者让两个需要操作的元素相邻起来(统计两个需要操作元素的中间有多少个元素)。
总结:思维被拷打,最后还没写出来,难题啊,这个代码的思路真的厉害,不仅处理了多个需要修改数值的情况,也考虑删除第一个前面所有字符,删除最后一个后面所有字符,以及全部字符都相等的情况。
void solve(){
int n;
cin >> n;
vector<int> a(n);
for (auto& x : a){
cin >> x;
}
int ans = n;
int last = -1;
for (int i = 0; i <= n; ++i){
if (i == n || a[i] != a[0]){
ans = min(ans, i - last - 1);
last = i;
}
}
if (ans == n){
ans = -1;
}
cout << ans << '\n';
}
C. Long Multiplication
题意:给定2个长度相等的字符串,可以交换字符串中相同位置的字符,求两个字符串相乘值最小时分别是多少。
思路:看输入输出,发现第一个不相等的字符后面,小的都往第一个字符大的串里放,其他的往第一个字符小的串里放。
总结:套路题,研究原理的话要研究一阵子呢,找规律就行。
void solve(){
string s, t;
cin >> s >> t;
int n = int(s.size());
bool firstTime = true;
for (int i = 0; i < n; ++i){
if (s[i] != t[i]){
if (firstTime){
if (s[i] < t[i]){
swap(s[i], t[i]);
}
firstTime = false;
}
else{
if (s[i] > t[i]){
swap(s[i], t[i]);
}
}
}
}
cout << s << "\n" << t << '\n';
}
D. Colored Balls
题意:n个颜色的球,每个颜色球的数量给出。定义value为当前若干个颜色球中最小的group数,group最多包含两个球,并且两个球颜色不能相同。
问2 ^ n种球的组合中,value一共是多少。
思路:首先,对于一个单独的组合,如果该组合中的最大值<=其他值的和,那么value就是该组合的(sum + 1) / 2,否则,value就是最大值。也就是说,对于每个组合,value的最小值是(sum + 1) / 2。基于这个思想,先用背包求出所有组合的sum的方案数,可以求出一个ans值。然后,要把剩下的一部分加进去,剩下的这部分怎么求呢?对于每个颜色,如果有某种组合的存在,那么这个组合的sum一定小于该颜色的物品数量a[i],而且之前已经添加过了(a[i] + sum + 1) / 2,只要再添加上a[i] - (a[i] + sum + 1) / 2,就是a[i]剩下的这部分单独一个颜色作为一个group的数量。
总结:只能想到对单个组合进行暴力破解,用dp的话,没想到如何转移这种状态。这个思路真的是太爆炸了,被震撼到了。
void solve() {
int n;
cin >> n;
const int mod = 998244353;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i){
cin >> a[i];
}
int s = std::accumulate(a.begin() + 1, a.end(), 0);
vector<long long> dp(s + 1);
dp[0] = 1;
for (int i = 1; i <= n; ++i){
for (int j = s; j >= a[i]; --j){
dp[j] += dp[j - a[i]];
dp[j] %= mod;
}
}
long long ans = 0;
for (int i = 1; i <= s; ++i){
ans += (1ll * i + 1) / 2 * dp[i];
ans %= mod;
}
for (int i = 1; i <= n; ++i){
for (int j = 0; j < a[i]; ++j){
ans += (a[i] - (a[i] + j + 1) / 2) * dp[j];
ans %= mod;
}
}
cout << ans << '\n';
}
标签:字符,Educational,Rated,颜色,int,Codeforces,cin,bob,dp
From: https://www.cnblogs.com/yxcblogs/p/18156865