比赛链接:https://arc098.contest.atcoder.jp/assignments
C:输入一个n,接下来输出一个长度为n的字符串,w为向西,e为向东,让找出一个人当领队,使其他所有人面向他,问怎样才能使人数转向最小(水题)
//先从左边先行扫描一遍,再从右边扫描一遍,两边加起来直接用总人数相减
//一定要优化! #include <iostream> #include <cstring> #include <cstdio> #include <string> using namespace std; const int maxn=1e6+10; int n; int l[maxn],r[maxn]; char str[maxn]; int maxx=0; int main() { scanf("%d",&n); scanf("%s",str); memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); for(int i=0;i<n;i++) { l[i]=l[i-1]; if(str[i]=='E') { l[i]++; } } for(int i=n-1;i>=0;i--) { r[i]=r[i+1]; if(str[i]=='W') { r[i]++; } } for(int i=0;i<n;i++) { r[i]=r[i]+l[i]; maxx=max(r[i],maxx); } cout<<n-maxx<<endl; return 0; }
D - Xor Sum 2
题意:给出n个数,求它的连续子序列中,满足下列公式,(l,r)的对数有多少对
Al xor Al+1 xor … xor Ar=Al + Al+1 + … + Ar
思路:由题意可以得到,连续子序列,如果在ai这个数不符合公式的话,即之后的符合条件的对数中将不在需要这个元素,所有枚举元素来计算符合公式的对数 。
#include <bits/stdc++.h> using namespace std; int n; int main() { ios::sync_with_stdio(false); cin>>n; vector<long long>a(n+1),xo(n+1),sum(n+1); for(int i=1;i<=n;i++) { cin>>a[i]; xo[i]=a[i]^xo[i-1]; sum[i]=sum[i-1]+a[i]; } long long l=0,ans=0; for(int i=1;i<=n;i++) { while((xo[i]^xo[l])!=sum[i]-sum[l]) { l++; } ans+=i-l; } cout<<ans<<endl; return 0; }
E - Range Minimum Queries
/* 本题因为要求n个连续数中取q个k长的子段,要找出每个子段最小的数,使这些最小的数中的最大的数-最小的数中的最小的数最小(不能有重复的数) 所以就可以大致归为在1-n个数中把每个数都看为最小(暂且成为A),并1-n中找到每个大于等于该数的数,当这些数的位置-A的位置>=子序列应该有 的长度的时候进行排序,当这些子序列中第q个元素-A即为当前中最小的,最后再从所有的数中找到最小的即可 */ #include <bits/stdc++.h> using namespace std; int inf=0x3f3f3f3f; int n,k,q; long long a[2010],t[2010],al[2010]; int work(int x) { int s=0,num=0,j; for(int i=1;i<=n+1;i++) { if(a[i]>=a[x]) { if(s==0) s=i;//标记大于等于该数的位置 } else if(s) { if(i-s>=k) //如果该数的位置减去要扫描的数的位置大于等于要求的区间, { for(j=s;j<i;j++)//s为大于该数的起始位置 { t[j-s+1]=a[j];//用数组t来记录这一个区间的数 } sort(t+1,t+i-s+1);//对数组t进行排序 for(j=1;j+k-1<=i-s;j++) //该区间因为是连续的,类似于5个数k=3时能取三段数,并用al数组记录 { num++; al[num]=t[j]; } } s=0;//位置归到0 } } if(num<q) return inf; sort(al+1,al+num+1); return al[q]-a[x]; } int main() { ios::sync_with_stdio(false); cin>>n>>k>>q; for(int i=1;i<=n;i++) cin>>a[i]; int ans=inf; for(int i=1;i<=n;i++) ans=min(ans,work(i)); cout<<ans<<endl; return 0; }