总结:4.18上午在宿舍V一场,打不下去,边写边玩。。。AC了A、B两题
A. Prefix and Suffix Array
思路:算是一道思维题,我的思路是找到长度为原字符串长度一半的字符串(因为如果是奇数中间的字符不需要考虑,如果是偶数则可以对半分),只需要对两个长度为原字符串长度一半的字符串正反遍历看是否相同即可
【reverse函数】reverse()反转函数
可对string和字符数组进行反转
reverse(N.begin(), N.end()); //string类型
reverse(a,a+m); //字符串数组
#include<iostream>
using namespace std;
int main(){
int T,n;
cin>>T;
while(T--){
cin>>n;
string s,s1,s2;
bool f=0;
for(int i=1;i<=2*n-2;i++){
cin>>s;
if(s.size()==n/2&&!f){
s1=s;
f=1;
}else if(s.size()==n/2){
s2=s;
}
}
for(int i=0,j=s1.size()-1;i<s1.size();i++,j--){
if(s1[i]!=s2[j]){
f=0;
break;
}
}
if(f){
cout<<"YES"<<'\n';
}else{
cout<<"NO"<<'\n';
}
}
return 0;
}
B. Not Dividing
思路:首先数组中不能出现1,因为1可以被任意数整除,如果输入1就把他变为2,再从下标2开始遍历,如果前一个数可以被这个数整除,这个数加1(切记不可前一个数加1,因为后一个数可能比前一个数大1,比如 2 3 2)
#include<iostream>
using namespace std;
const int N=10005;
int a[N];
int main(){
int T,n;
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1){
a[i]++;
}
}
cout<<a[1]<<' ';
for(int i=2;i<=n;i++){
if(a[i]%a[i-1]==0){
a[i]++;
}
cout<<a[i]<<' ';
}
cout<<'\n';
}
return 0;
}
C. Scoring Subsequences
两种思路:multiset和双指针
关于multiset:multiset用法总结
思路一:multiset能时刻保证序列中的数是有序的,而且序列中可以存在重复的数,所以就每次看multiset中的第一个数是否大于等于元数个数,若不是就删去第一个数
#include<iostream>
#include<set>
using namespace std;
multiset<int>s;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T,n,x;
cin>>T;
while(T--){
s.clear();
cin>>n;
for(int i=1;i<=n;i++){
cin>>x;
s.insert(x);
while(s.size()>1&&*s.begin()<s.size()){
s.erase(s.begin());
}
cout<<s.size()<<' ';
}
cout<<'\n';
}
return 0;
}
思路二:(双指针)
#include<iostream>
using namespace std;
const int N=100005;
int a[N];
int main(){
int T,n;
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int l=1,r=1;
while(r<=n){
while(r-l+1>1&&a[l]<r-l+1){
l++;
}
cout<<r-l+1<<' ';
r++;
}
cout<<'\n';
}
return 0;
}