链接
Dashboard - Codeforces Round 923 (Div. 3) - Codeforces
A. Make it White
题意:给定一个n长的字符串s,s中包含W和B,可以选定一个区间,使得其中所有的B变为W,求让所有B变为W的最小区间
思路:选定最早的B和最晚的B就是这个区间长度了
代码:
#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=1e5+7;
int n,q;
ll a[N],temp[N],ans[105];
inline void solve()
{
cin>>n;
string s;
cin>>s;
int minn=1e9,maxn=-1;
for(int i=0;i<s.length();i++){
if(s[i]=='B'){
minn=min(minn,i);
maxn=max(maxn,i);
}
}
ll ans=maxn-minn+1;
cout<<max(0LL,ans)<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
B. Following the String
题意:存在一个n长的字符串s,给了一个数组a,其中ai表示si前面有多少个字符和si一样。
思路:暴力模拟,用个book标记一下,book[i]表示i+‘a’出现了多少次。
代码:
#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=1e5+7;
int n,q;
ll a[N],temp[N],ans[105];
inline void solve()
{
int n;
cin>>n;
vector<int> book(n+1);
string s="";
for(int i=1;i<=n;i++){
int x;
cin>>x;
s+=(char)(book[x]+'a');
book[x]++;
}
cout<<s<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
C. Choose the Different Ones!
题意:给定n,m,k,n个数字的a数组,m个数字的b数组,询问是否可以各取k/2个数组,组成一个新的数组包含1-k
思路:首先要求a有k/2个及以上1-k的数组,对b也是;这些数组分别对于a、b重复的是不累加的,然后再扫一遍看看是否1-k都有了就行了
代码:
#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=1e5+7;
inline void solve()
{
int n,m,k;
cin>>n>>m>>k;
set<int> a,b;
int cnta=0,cntb=0;
vector<int> book(k+1);
for(int i=1;i<=n;i++){
int x;
cin>>x;
if(1<=x&&x<=k){
if(a.find(x)==a.end()){
cnta++;
book[x]=1;
a.insert(x);
}
}
}
for(int i=1;i<=m;i++){
int x;
cin>>x;
if(1<=x&&x<=k){
if(b.find(x)==b.end()){
cntb++;
book[x]=1;
b.insert(x);
}
}
}
if(cnta>=k/2&&cntb>=k/2){
for(int i=1;i<=k;i++){
if(!book[i]){
cout<<"NO"<<endl;
return;
}
}
cout<<"YES"<<endl;
return;
}
//cout<<"this"<<endl;
cout<<"NO"<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
D. Find the Different Ones!
题意:给定一个数组a有n个数字,然后有q个询问,每次询问给出一个l和r,要求对于数组a[l]到a[r]是否存在下标x,y使得a[x]!=a[y],同时l<=x<y<=r.
思路:对于每一个下标,预处理他的左边第一个和他不一样的位置就行,如果和前一个不一样就是前一个,不然就等于前一个的不一样的位置,因为此时是和前一个一样的,直接继承就可以了。
代码:
#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=2e5+7;
int n,q;
int a[N];
inline void solve()
{
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
vector<int> p(n+1);
p[1]=0;
for(int i=2;i<=n;i++){
p[i]=p[i-1];
if(a[i]!=a[i-1]){
p[i]=i-1;
}
}
cin>>q;
while(q--){
int l,r;
cin>>l>>r;
if(p[r]<l){
cout<<"-1 -1"<<endl;
}
else{
cout<<p[r]<<" "<<r<<endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
E. Klever Permutation
题意:给定n和k,要求利用1-n的数字去构造一个长为n的数组,数字不重复,同时对于任意一对长为k的区间的和,要求差不超过1。
思路:要求差不超过1,说明只能构造数组s,si代表ai-ai+k-1的区间和,si=s(i+1)+1或者si=s(i+1)-1,可以是连续的下降或者是一起一落。
然后对于相邻的si和si+1,区别就是ai和ai+k相差1,对于每个i去构造n/k个数字就行了。
代码:
#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=2e5+7;
int n,k;
int a[N];
inline void solve()
{
int n,k;
cin>>n>>k;
int l=1,r=n;
vector<int> ans(n+1);
for(int i=1;i<=k;i++){
for(int j=i;j<=n;j+=k){
if(i%2==1){
ans[j]=l;
l++;
}
else{
ans[j]=r;
r--;
}
}
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
cout<<endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}