能力不够只写了前4题 第四题在赛后10来分钟才调出来 又又又要掉分了
A. Replacing Elements
题意: 你可以做任意次操作 操作方法为选择 ai aj 使得 ak=ai+ak
问你能不能 使得数组全部小于d
思路:从前往后递推即可 只需要找出 是否存在2个数相加小于等于d 或者所有值都小于等于d
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
int n,k;
scanf("%d%d",&n,&k);
priority_queue<int, vector<int>, greater<int>> q;
int flag=1;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
q.push(x);
if(x>k)flag=0;
}
int x1=q.top();
q.pop();
int x2=q.top();
if(x1+x2<=k||flag)puts("YES");
else puts("NO");
}
return 0;
}
B. String LCM
题意:是否能有 ax=by然后输出a*x
思路:首先判断是否可行 即字符串是否有循环节 即是否存在a+b==b+a
然后通过LCM最大公倍数 输出结果即可
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int gcd(int x,int y){
return y ? gcd(y,x%y) : x;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int main(){
int T;
cin>>T;
while(T--){
string a,b;
cin>>a>>b;
if(a+b==b+a){
int l1=a.size(),l2=b.size();
int g=lcm(l1,l2);
for(int i=1;i<=g/l1;i++)
cout<<a;
puts("");
}
else puts("-1");
}
return 0;
}
C. No More Inversions
题意:b数组为 p[a] 即 b1 b2 b3 为p[a1] p[a2] p[a3]
在满足b数组逆序对不超过a的情况下 b的字典序最大
思路:找规律 一开始我看假题 以为是p与a比 p的字典序最大 花了很长时间
后续草稿纸上写了几个 盲猜结论过了 血亏
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
int gcd(int x,int y){
return y ? gcd(y,x%y) : x;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int main(){
int T;
cin>>T;
while(T--){
int n,k;
cin>>n>>k;
int nk=n-k;
for(int i=1;i<k-nk;i++){
printf("%d ",i);
}
for(int i=k;i>=k-nk;i--)
printf("%d ",i);
cout<<endl;
}
return 0;
}
D - Program
题意x从0开始 给出一段字符串从前往后一次进行操作
+为+1 -为-1
问 在忽略掉l到r区间后 有多少种数字
思路:区间问题首先想到了线段树 但是我没想到线段树的解法 后来发现从前处理一次 然后从后处理一次 维护最大每一位的差值 从后往前处理的是 从i到n的max 和 min 从前往后处理的是从1到 i 的max和min
其中在从后往前转移时 需要用一个额外的数组进行转移 赛时就是这里出了点问题
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10;
int max1[N],min1[N],max2[N],min2[N],sum1[N],max21[N],min21[N];
char s[N];
int main(){
int T;
cin>>T;
while(T--){
memset(min1,0,sizeof min1);
memset(max1,0,sizeof max1);
memset(min2,0,sizeof min2);
memset(max2,0,sizeof max2);
memset(min21,0,sizeof min2);
memset(max21,0,sizeof max2);
memset(sum1,0,sizeof sum1);
int n,k;
cin>>n>>k;;
scanf("%s",s+1);
int sum=0;
for(int i=1;i<=n;i++){
char op=s[i];
if(op=='-')
sum--;
else sum++;
min1[i]=min(min1[i-1],sum);
max1[i]=max(max1[i-1],sum);
sum1[i]=sum;
}
sum=0;
for(int i=n;i>=1;i--){
char op=s[i];
if(op=='-')
sum--;
else sum++;
max21[i]=max(sum,max21[i+1]);
min21[i]=min(sum,min21[i+1]);
min2[i]=min(min(0,sum),sum-max21[i+1]);
max2[i]=max(max(sum,0),sum-min21[i+1]);
}
for(int i=1;i<=k;i++){
int l,r;
scanf("%d%d",&l,&r);
int ans=max1[l-1]-min1[l-1]+1;
int now = sum1[l-1];
if(now+max2[r+1]>max1[l-1])ans+=now+max2[r+1]-max1[l-1];
if(now+min2[r+1]<min1[l-1])ans+=min1[l-1]-now-min2[r+1];
printf("%d\n",ans);
}
}
}