题目链接:
A. Short Substrings
B. Even Array
C. Social Distance
D. Task On The Board
A. Short Substrings
题意:将字符串a的所有长度为2的子串连接形成新字符串,算出原字符串a
题解:直接跳过重复的即可
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int t;
int main()
{
cin>>t;
while(t--){
string a;
cin>>a;
cout<<a[0];
for(int i=1;i<a.size();i++){
cout<<a[i];
if(i%2==1) i++;//去掉重复的
}
cout<<endl;
}
return 0;
}
B. Even Array
题意:交换数组中元素位置,使得下标与各元素同奇偶,如果可以输出交换次数,否则输出-1。
题解:分别记录下标为奇元素为偶的个数(q)和下标为偶元素为奇的个数(w),如果q=w,则输出q,反正-1。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a;
int t,n;
int main()
{
cin>>t;
while(t--){
cin>>n;
int q=0,w=0;
for(int i=0;i<n;i++){
cin>>a;
if(i%2==0&&a%2==1) q++;
else if(i%2==1&&a%2==0) w++;
}
if(q==w) cout<<q<<endl;
else if(q!=w) cout<<-1<<endl;
}
return 0;
}
C. Social Distance
题意:给定一个二进制字符串,保证每个1之间间隔k个0,问可以放多少个1。
题解:谈论四种情况:
1、当前k+1个都为0时,就在第一个位置加1;
2、如果在中间有连续2k+1个0时,就在其中间加1;
3、如果在字符串尾部有连续k+1及以上 个0时,就在结尾加1;
4、如果字符串长度等于k,则答案为1;
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int a,x;
int t,n,k;
int main()
{
cin>>t;
while(t--){
cin>>n>>k;
int q=0,w=0,c=0;
char x;
for(int i=0;i<n;i++){
cin>>x;
if(x=='0') w++,q++;
else if(x=='1') q=0;
if(q==k+1&&i==k) c++,q=k;
//第一种情况
else if(q==2*k+1) c++,q=k;
//第二种情况
}
if(q>=k+1) c++;
//第三种情况
if(w==n&&c==0) c++;
//第四种情况
cout<<c<<endl;
}
return 0;
}
D. Task On The Board
题意:For example, if t = “abzb”, then:
since t1=‘a’, all other indices contain letters which are later in the alphabet, that is: b1=|1−2|+|1−3|+|1−4|=1+2+3=6;
since t2=‘b’, only the index j=3 contains the letter, which is later in the alphabet, that is: b2=|2−3|=1;
since t3=‘z’, then there are no indexes j such that tj>ti, thus b3=0;
since t4=‘b’, only the index j=3 contains the letter, which is later in the alphabet, that is: b4=|4−3|=1.
Thus, if t = “abzb”, then b=[6,1,0,1].
题解:注意b[j]=0的点,因为为0,所以他应该放的是最大的值。
我们只需要将最大的字母放在b[j]==0处,其他的地方都应该是小于他的,所以其他位置的数字会变成b[i]-=abs(i-j),以此类推,每一次为0的点都放剩下字母中最大且数目足够是字母,一直循环到结束即可。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int q,m,x,b[60],v[27];
string a;
int vis[60];
char da[60];
int main()
{
cin>>q;
while(q--){
memset(v,0,sizeof v);
memset(vis,0,sizeof vis);
memset(da,'0',sizeof da);
cin>>a>>m;
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
for(int i=0;i<a.size();i++) v[a[i]-'a'+1]++;
//下标表示字母的大小,值代表个数
int num=0,zero=0,k=27;
while(num!=m){//判断m个位置是否都放了
zero=0;
int c=0;
for(int i=1;i<=m;i++) if(b[i]==0&&vis[i]==0) zero++;
//记录当前为0的数目
for(int i=k-1;i>0;i--)
if(v[i]>=zero) {k=i;break;}
//寻找最大且数目足够的字母
for(int i=1;i<=m;i++) {
if(b[i]==0&&vis[i]==0){
vis[i]++;num++;
//记录已经存放的位置和个数
da[i]=k+'a'-1;
//将字母存入
}
}
for(int i=1;i<=m;i++){
if(b[i]==0&&da[i]==k+'a'-1)
for(int j=1;j<=m;j++)
if(b[j]) b[j]-=abs(j-i);
//其他位置都应该小于当前加入的字母,
//所以前去位置差
}
}
for(int i=1;i<=m;i++) cout<<da[i];
cout<<endl;//输出
}
return 0;
}