A
思路: 任意相邻元素之和为偶数,那么这两个数定是两个偶数或者奇数,也就意味者整个序列只能有奇数或者偶数。
signed main(){
cin >> t;
while (t --) {
cin >> n;
int a = 0, b = 0;
for (int i = 1; i <= n; i ++) {
cin >> x;
if (x % 2) a ++;
else b ++;
}
cout << min(a, b) << endl;
}
return 0;
}
B
思路:要求每个人之间换一个数,每个人只能换大于等于他的数,那么这就意味着,只能换等于他的数,因为换大于他的数,原来的那个人就只有去找更大的了,最后,一定会有一个人找不到数可以换。
每个人对于和他自己相等的数,移动一个位置即可
signed main(){
tle
cin >> t;
while (t --) {
cin >> n;
map<int, vector<int>> mp;
for (int i = 1; i <= n; i ++) cin >> x, mp[x].push_back(i);
int f = 1;
for (auto& t : mp)
if (t.second.size() < 2) f = 0;
else {
auto& p = t.second;
int l = p.size();
for (int i = 0; i < l; i ++)
s[p[i]] = p[(i + 1)%l];
}
if (f) {
for (int i = 1; i <= n; i ++) cout << s[i] << " ";
cout << endl;
} else cout << -1 << endl;
}
return 0;
}
C
思路:01100 和 01010 其实没有区别,区别在于消除头和尾部的0
消除尾部的0,赚10
消除头部的0,赚1
头尾消除完就没了
signed main(){
tle
cin >> t;
while (t --) {
cin >> n >> k;
string s;int ans = 0;
cin >> s;
for (int i = n - 1; i >= 0; i --) {
if (s[i] == '1') {
int st = i;
if (i + k >= n - 1) {
swap(s[i], s[n - 1]);
k -= n - 1 - i;
st --;
}
for (int j = 0; j <= st; j ++) {
if (s[j] == '1'){
if (k >= j)
swap(s[j], s[0]);
break;
}
}
break;
}
}
for (int i = 0; i < n - 1; i ++) {
if (s[i] == '1' && s[i + 1] == '1') ans += 11;
else if(s[i] == '1' && s[i + 1] == '0') ans += 10;
else if (s[i] == '0' && s[i + 1] == '1') ans += 1;
}
cout << ans << endl;
}
return 0;
}
D
思路:找出一段和大于这一段的max。对于一段的和,在某一个区间内
找出以[i, r]范围内某一个点的最大前缀和去减去[l, i-1]范围内的最小的前缀和。 为保证i点为最大,我们需要找到i左边和i右边大于i的第一个数。
这个点上,可以用单调栈来求。
某一段上的最大值和最小值,可以用st表来求。
int k;
int l[N], r[N], st[N], idx;
int mins[N][31], maxs[N][31], pre[N];
signed main(){
tle
cin >> t;
pre[1] = 0;
pre[2] = 1;
for (int i = 3; i < N; i ++) pre[i] = pre[i / 2] + 1;
while (t --) {
cin >> n;
for (int i = 1; i <= n; i ++)
cin >> g[i], s[i] = s[i - 1] + g[i],
mins[i][0] = maxs[i][0] = s[i];
st[0] = 0;
for (int i = 1, idx = 0; i <= n; i ++) {
while(idx && g[st[idx]] <= g[i]) idx --;
l[i] = st[idx];
st[++ idx] = i;
}
st[0] = n + 1;
for (int i = n, idx = 0; i >= 1; i --) {
while(idx && g[st[idx]] <= g[i]) idx --;
r[i] = st[idx];
st[++ idx] = i;
}
for (int j = 1; (1 << j) <= n; j ++)
for (int i = 1; i + (1 << j) - 1 <= n; i ++) {
mins[i][j] = min(mins[i][j - 1], mins[i + (1 << (j - 1))][j - 1]);
maxs[i][j] = max(maxs[i][j - 1], maxs[i + (1 << (j - 1))][j - 1]);
}
int f = 1;
for (int i = 1; i <= n && f; i ++) {
int zl = l[i], zr = r[i] - 1, j, a = 0, b = 1e18;
j = pre[zr - i + 1];
a = max(maxs[i][j], maxs[zr - (1 << j) + 1][j]);
if (!zl) zl ++, b = 0;
j = pre[i - zl];
if (i != zl)
b = min(b, min(mins[zl][j], mins[i - (1 << j)][j]));
//printf("%lld %lld | %lld %lld\n", a, b, zl, zr);
if (g[i] < a - b) f = 0;
}
cout << (f ? "YES" : "NO") << endl;
}
return 0;
}