Educational Codeforces Round 93 (Rated for Div. 2)
A. Bad Triangle
题解:
其实这个题很水的…
之前做过一个给出你四个数让你组三角形,这一次就是要求不一样。我们已知a序列是一个非递减序列,那么如果a种存在题目所说的BT的话,那么一定包括a[1]和a[2],因为不管i,j取何值,相加后的结果一定是:a[i] + a[j] <= a[1] + a[2]
,所以用a[1]和a[2]凑出这个BT三角就完了。
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int maxn = 5e4 + 10;
ll a[maxn] = {0};
int main()
{
int t;
cin >> t;
while(t--){
int n;
memset(a,0,sizeof(a));
cin >> n;
for(int i = 1;i <= n;i++) cin >> a[i];
ll temp = a[1] + a[2]; //第一次卡在这个long long上
int flag = 0,ans;
for(int i = 3;i <= n;i++){
if(temp <= a[i]){
// cout << 1 << ' ' << 2 << ' ' << i << endl;
flag = 1;
ans = i;
break;
}
}
if(flag) cout << 1 << ' ' << 2 << ' ' << ans << endl;
else cout << -1 << endl;
}
return 0;
}
B.Substring Removal Game
题解:
还是一道800分的水题…
不知道为啥EDU的题目总是很让人难受,之前就是第二题上1700这一次就是两道800…
既然是能删除连续的序列而且删除1越多的一方获胜,那么就是求出原序列中所有连续1序列的个数,然后排个序取奇数个就可以了
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 1e3 + 10;
int a[maxn] = {0};
bool cmd(int a,int b)
{
return a > b;
}
int main()
{
int t;
cin >> t;
while(t--){
string ss;
cin >> ss;
int len = ss.length();
ss = "#" + ss;
int num1 = 0,cnt = 0;
for(int i = 1;i <= len;i++){
if(ss[i] == '1') num1++;
if(ss[i] == '0' && num1) {
a[++cnt] = num1;
num1 = 0;
}
if(i == len && num1) a[++cnt] = num1;
}
// cout << "cnt = " << cnt << endl;
int ans = 0;
sort(a + 1,a + 1 + cnt,cmd);
for(int i = 1;i <= cnt;i++){
if(i % 2 == 1) ans += a[i];
}
cout << ans << endl;
}
return 0;
}
C.Good Subarrays
题解:
挺好的一题,前些天其实刚在蓝书上看见了…我太菜了
既然要求元素之和和序列长度相同,那就意味着我们把元素值统一减一后得到的和应该是0。考虑前缀和,这个题目就是转化成求这一序列中有多少前缀和为0的序列。
但是如果出现一个前缀和为0的序列中包括上一个前缀和为0的序列怎么办?我们可以用一个map维护一下前缀和,然后每一次更新ans的时候都进行一次加法。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
const int maxn = 1e5;
int a[maxn];
map<ll,ll> mp;
int main()
{
int t;
cin >> t;
while(t--){
int n;
ll ans = 0,sum = 0;
string s;
cin >> n >> s;
mp.clear();
s = "#" + s;
for(int i = 1;i <= n;i++){
sum += s[i] - '0' - 1; //统一减一维护
if(sum == 0) ans += 1; //如果此时前缀和是0,那就加一(1~该位置的序列)
ans += mp[sum]; //更新答案(参照0 0 1 0 0 -1的样例)
mp[sum]++; //维护前缀和
}
cout << ans << endl;
}
return 0;
}