D. Mishkin Energizer
题意:给定一个只包含3个字母{T, L, I}的长度为n的字符串,可以进行最多2 * n次操作,每次操作选取一个位置i, 保证s[i] != s[i + 1], 然后插入一个 != s[i] && != s[i + 1]的字符,最后要保证每个字母出现的次数一样多,最后输出每次操作的位置,如果无法满足要求,输出-1
思路:首先特判这个字符串如果只有一种字符,那肯定是没有任何操作空间的。然后通过模拟, 假设此时的字符串是a bbb, 那么第1个a和第1个b之间我是可以一直产生a和c的,最后变成acacabbb, 当这时候我们只有继续插入b,才能继续操作,所有我们可以发现,我们一定是优先让数量最小的字符尽可能的大,当我们数量第二小的字符和数量最多的字符数量一样时,我们就无法再操作了,接着只有插入数量最多的字符才能进行操作,至于这样操作为什么是保证 <= n * 2, 直接猜就完了^-^, 官方给的证明也没看懂.
总结:我们的模拟过程大致就是,先找到此时位置可以插入哪个字母,然后判断这个字母是不是数量最少的,是就插进去,如果我操作不了数量最小的字母,那就插入数量最多的字母,继续模拟,因为 n <= 100,所以每次模拟1遍插入1个字符慢慢来就可以
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
string s;
cin >> s;
map<char,int> mp;
vector<int> ans;
vector<char> a {'L', 'I', 'T'};
string tmp = s;
sort(tmp.begin(), tmp.end());
if(tmp[0] == tmp[tmp.size() - 1])
{
cout << -1 << '\n';
continue;
}
for(int i = 0; i < s.size(); i ++)
{
mp[s[i]] ++;
}
auto get = [&](int u) -> char{
for(int i = 0; i < a.size(); i ++)
{
if(a[i] != s[u] && a[i] != s[u + 1]) return a[i];
}
return '0';
};
while(max(mp['L'], max(mp['I'], mp['T'])) != min(mp['L'], min(mp['I'], mp['T'])))
{
bool f = false;
int minn = min(mp['L'], min(mp['I'], mp['T']));
int maxn = max(mp['L'], max(mp['I'], mp['T']));
for(int i = 0; i < s.size() - 1; i ++)
{
char c = get(i); // 找到此位置可以插入的字符
if(s[i] != s[i + 1] && mp[c] == minn)
{
f = true;
mp[c] ++;
s.insert(s.begin() + i + 1, 1, c);
ans.push_back(i);
break;
}
}
if(!f) // 只能操作数量最多的字符
{
for(int i = 0; i < s.size() - 1; i ++)
{
char c = get(i);
if(s[i] != s[i + 1] && mp[c] == maxn)
{
f = true;
mp[c] ++;
s.insert(s.begin() + i + 1, 1, c);
ans.push_back(i);
break;
}
}
}
}
cout << ans.size() << '\n';
for(auto i : ans) cout << i + 1 << '\n';
}
return 0;
}
C. Asuna and the Mosquitoes
题意:给定n个整数,每次选两个和为奇数的数,一个加1一个减1,让数组的最大值最大;
思路:通过模拟样例可以发现,奇数的个数永远是不变的,所以最大值就是吃掉所有偶数,再让本身外的奇数都变成1即可
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;
typedef pair<int,int> PII;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
vector<int> b;
vector<int> c;
for(int i = 0; i < n; i ++)
{
int x;
cin >> x;
if(x % 2) b.push_back(x);
else c.push_back(x);
}
if(c.empty())
{
int maxn = 0;
for(int i = 0; i < b.size(); i ++)
{
maxn = max(maxn, b[i]);
}
cout << maxn << '\n';
}
else if(b.empty())
{
int maxn = 0;
for(int i = 0; i < c.size(); i ++)
{
maxn = max(maxn, c[i]);
}
cout << maxn << '\n';
}
else
{
sort(b.begin(), b.end());
int ans = b[b.size() - 1];
for(int i = 0; i < c.size(); i ++)
{
ans +=c[i];
}
for(int i = 0; i < b.size() - 1; i ++)
{
ans += b[i] - 1;
}
cout << ans << '\n';
}
}
return 0;
}
B. Lady Bug
思路:根据题意画图,红色的线上都是可以互换的,蓝色的线上都是可以互换的,统计每一条线上0的个数即可
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;
typedef pair<int,int> PII;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
string a, b;
cin >> a >> b;
int cnt_a = 0;
int cnt_b = 0;
for(int i = 0; i < n; i ++)
{
if(a[i] == '1') cnt_a ++;
if(b[i] == '0') cnt_b ++;
}
if(cnt_a > cnt_b) cout << "NO" << '\n';
else
{
int cnt1 = 0;
int cnt2 = 0;
a = " " + a;
b = " " + b;
for(int i = 1; i <= n; i ++)
{
if(i % 2)
{
if(a[i] == '0') cnt1 ++;
if(b[i] == '0') cnt2 ++;
}
else
{
if(a[i] == '0') cnt2 ++;
if(b[i] == '0') cnt1 ++;
}
}
if(n % 2)
{
if(cnt1 >= n / 2 + 1 && cnt2 >= n / 2) cout << "YES" << '\n';
else cout << "NO" << '\n';
}
else
{
if(cnt1 >= n / 2 && cnt2 >= n / 2) cout << "YES" << '\n';
else cout << "NO" << '\n';
}
}
}
return 0;
}
A. Kamilka and the Sheep
思路:先根据样例猜一下结论,然后简单玩几个样例就可以发现了
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define int long long
using namespace std;
typedef pair<int,int> PII;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
vector<int>a(n, 0);
for(int i = 0; i < n; i ++) cin >> a[i];
sort(a.begin(), a.end());
cout << a[n - 1] - a[0] << '\n';
}
return 0;
}