Codeforces Round 923 (Div. 3)A~D做题分享
这次的比赛A出了3道题,状态不算好有点感冒,好久不打\(CF\)了,但是能感觉出自己的
进步,比之前好多了,A~D题都能想出正确的思路,但在取舍上不够果断,还是太急总
是想马上写出来,实际上多想一会儿能少走许多弯路。
虽然比赛只写出了三道题,但感觉还算满意,做题的正确思路得出的越来越快,但是代
码实现和代码速度以及思路(这里指代码实现的思路)的判断还需要加强。
分享下我的做题过程吧。
A. Make it White
这个题一眼看出思路算是能感觉出自己在变强。
思路很简单便是找到第一个B和最后一个B的位置,做差加一便是答案。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 2e6 + 10;
const int M = 10100;
void solve()
{
int n;
cin >> n;
string s;
cin >> s;
int i;
int a, b;
for (i = 0; i < s.size(); i++)
{
if (s[i] == 'B')
{
a = i ;
break;
}
}
for(i=s.size()-1;i>=0;i--)
{
if(s[i]=='B')
{
b=i;
break;
}
}
cout<<b-a+1<<'\n';
}
signed main()
{
int t = 1;
cin >> t;
while (t--)
solve();
}
B. Following the String
这个题便是想多了,\(CF\)的时间复杂度总是给我一种过不去的感觉,但实际上这个题暴力查询即可。。。。挺无语的想了那么久。。。
使用map映射a~z的数目,对于给出的 \(a[ i ]\)找到与值对应的map的映射字母即可。。。。。。。。。乌鱼
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 2e6 + 10;
const int M = 10100;
int a[N];
signed main()
{
int t = 1;
scanf("%lld", &t);
while (t--)
{
int n;
scanf("%lld", &n);
int i;
// char op = 'a';
// int q[1000] = {0};
map<char, int>ma;
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
for (i = 0; i < 26; i++)
{
ma['a' + i] = 0;
}
for (i = 1; i <= n; i++)
{
for (int j = 0; j < 26; j++)
{
if (ma[j + 'a'] == a[i])
{
printf("%c", 'a' + j);
ma['a' + j]++;
break;
}
}
}
puts("");
}
}
/*
0 0 0 1 2 3 1 2 3 4 1
a b c c c c b b b b a
11
0 0 0 1 0 2 0 3 1 1 4
a b c c d
a b c c c c c c b a a
*/
C. Choose the Different Ones!
罚时了几发,感觉大脑不太清醒,明明只要静下心一想就能知道判断条件,但自己不
知道为什么鬼使神差去找选择元素的方法。。。找到判断条件后一直守着自己开始的
的代码改,我也是服了莫名其妙写了个二分细想就知道不需要我也没删,,,最后10
分钟我痛定思痛,果断重构删掉二分,距离结束4分钟A出了这道题,最最最sb的一
集。
思路:排序+去重,首先判断 \(1\) 到 \(k\) 内所有的数是否都出现过,然后判断a和b
数组内分别出现多少个1~k内的元素,如果出现的元素个数都\(≥k/2\)那么就说明一定
可以满足条件,有点集合的感觉,想象成集合就好理解多了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 2e6 + 10;
const int M = 10100;
int a[N], b[N], q[N];
void solve()
{
int n, m, k;
cin >> n >> m >> k;
int i;
for (i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
}
for (i = 1; i <= m; i++)
{
scanf("%lld", &b[i]);
}
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + m);
int ans = unique(a + 1, a + 1 + n) - (a + 1);
int res = unique(b + 1, b + 1 + m) - (b + 1);
// cout<<ans<<" "<<res<<'\n';
int sa = 0;
int sb = 0;
for (i = 1; i <= k; i++)
{
q[i] = 0;
}
for (i = 1; i <= ans; i++)
{
if (a[i] <= k)
{
q[a[i]] = 1;
sa++;
}
}
for (i = 1; i <= res; i++)
{
if (b[i] <= k)
{
q[b[i]] = 1;
sb++;
}
}
for (i = 1; i <= k; i++)
{
if (q[i] != 1)
{
puts("NO");
return;
}
}
// cout<<sa<<" "<<sb<<'\n';
if (sa >= k / 2 && sb >= k / 2)
{
puts("YES");
}
else
{
puts("NO");
}
}
signed main()
{
int t = 1;
scanf("%lld", &t);
while (t--)
{
solve();
}
}
/*
6 5 6
2 3 5 6 8
1 3 4 5 10
6 5 6
2 3 4 5 6
1 3 8 10
*/
D. Find the Different Ones!
这是赛后做的,赛后也是很快想出来了思路,比赛里时间肯定不够了。
思路:双指针,找到右边第一个与当前元素不同的元素即可,用pair记录两个下标,
查询时如果\(r≥pa[l].second\),那就说明这个区间里有和他不同的数输出下标即可,
否则输出-1 -1。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 2e6 + 10;
const int M = 10100;
int a[N], b[N], q[N];
void solve()
{
int n;
cin >> n;
int i, j = 1;
for (i = 1; i <= n; i++)
scanf("%lld", &a[i]);
pair<int, int> pa[n+100];
for (i = 1; i <= n;)
{
if (a[i] == a[j])
{
j++;
// if(j>n)
// {
// pa[i].first=0;
// pa[i].second=0;
// }
}
else if (a[i] != a[j])
{
pa[i].first = i;
pa[i].second = j;
while (i < j)
{
pa[i].first = i;
pa[i].second = j;
i++;
}
i = j;
}
}
// for (i = 1; i <= n; i++)
// {
// cout << pa[i].first << ' ' << pa[i].second << '\n';
// }
int q;
cin >> q;
while (q--)
{
int l, r;
cin >> l >> r;
if (r >= pa[l].second)
{
cout << pa[l].first << " " << pa[l].second << '\n';
}
else
{
cout << "-1 -1" << '\n';
}
}
}
signed main()
{
int t = 1;
scanf("%lld", &t);
while (t--)
{
solve();
}
}
/*
5
1 4 3 2 4
很一ban啊
5
1 1 2 1 1
*/